Compare commits

..

239 Commits

Author SHA1 Message Date
pvictor 5f8389ff34 updated slope chart example 2024-05-22 11:15:58 +02:00
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
pvictor 8ce6afc5f5 bump version 2020-06-23 11:14:13 +02:00
pvictor 296797c353 rebuilt pkgdown 2020-06-23 10:49:20 +02:00
pvictor 273936b151 updated GitHub actions 2020-06-13 16:05:50 +02:00
pvictor 31f824b5d5 updated pkgdown 2020-06-13 13:06:58 +02:00
pvictor 9d5158c024 updated NEWS and vignette 2020-06-13 13:04:23 +02:00
pvictor 7712ab2e64 candles demo data 2020-06-13 13:04:10 +02:00
pvictor e6ae2ac8c8 added candlestick support 2020-06-13 12:18:02 +02:00
pvictor d25bf7f7d7 bump version 2020-06-09 17:03:49 +02:00
pvictor 47d8a9c15a date xaxis: sort 2020-06-09 17:03:35 +02:00
pvictor ebbaf381d1 spark axis: be sure axis is hidden 2020-06-09 17:02:39 +02:00
pvictor ce1ea38e73 updated apexcharts.js 2020-06-09 17:02:07 +02:00
pvictor 9e1e61561b updated pkgdown 2020-05-27 16:29:28 +02:00
pvictor 7da1efd19c merged vignettes labs and lines 2020-05-27 14:28:13 +02:00
pvictor 9aea6b8e9e updated Apexcharts to 3.19.2 2020-05-27 14:27:50 +02:00
pvictor 738e281777 config for no data 2020-05-27 11:42:42 +02:00
pvictor b9bc804e28 fixed bug multi 2020-04-29 18:24:39 +02:00
pvictor 8c471242f0 axis labs & pre-multi 2020-04-29 11:35:06 +02:00
pvictor 6ebd778537 labs adjustments 2020-04-29 11:14:54 +02:00
pvictor 6e91a515de position in annotations 2020-04-28 11:15:33 +02:00
pvictor 48d4aa0362 updated Apexcharts to 3.19.0 and locales 2020-04-27 14:52:04 +02:00
pvictor 5693403b68 more chart type in apex() 2020-04-17 20:21:57 +02:00
pvictor c8ff4986b5 added bubble options 2020-04-17 16:46:34 +02:00
pvictor 311dc0f18d added add_event_marker() 2020-04-17 11:29:11 +02:00
pvictor ddf9bb3294 columns in spark box 2020-04-17 11:28:54 +02:00
pvictor 9c9a277aee x-axis datetime for column & scatter 2020-04-17 08:57:23 +02:00
pvictor 7dc81c6db6 updated deps 2020-04-16 18:12:36 +02:00
pvictor 5704d62220 rebuild pkgdown 2020-04-16 17:09:40 +02:00
pvictor 0fdba4cd9b added ga 2020-04-16 16:49:20 +02:00
pvictor 2b1fc484b7 news & clean up 2020-04-16 16:43:50 +02:00
pvictor 78d09c3316 added spark box 2020-04-16 16:42:34 +02:00
pvictor 27673fb980 added synchronize arg to apex 2020-04-15 19:32:15 +02:00
pvictor 02cf03fd6a fixed resizing bug with auto update + dont update synced charts options 2020-04-15 16:20:29 +02:00
pvictor ea901187ac better auto update method 2020-04-15 14:41:15 +02:00
pvictor 5728a361da Updated ApexCharts.js to 3.18.1 2020-04-06 12:28:05 +02:00
pvictor 1a6063e9fb fixed darkmode, 2nd yaxis example, NEWS 2020-04-04 19:11:10 +02:00
pvictor 79f04f26da added set_tooltip_fixed() 2020-04-04 18:38:12 +02:00
pvictor 8d751a485e added add_point() 2020-04-04 13:05:19 +02:00
pvictor 92b2217f56 added add_hline() and add_vline() 2020-04-04 12:36:42 +02:00
pvictor 721cce9cff added add_event() 2020-04-03 20:16:26 +02:00
pvictor dc10f5e2b1 annotations internals 2020-04-03 16:15:18 +02:00
pvictor a96755e1c0 added label() for annotations 2020-04-03 15:26:01 +02:00
pvictor f7a8df7277 add_shade example 2020-04-02 19:38:49 +02:00
pvictor d3126ab26b add_shade() & add_shade_weekend() 2020-04-02 19:33:39 +02:00
pvictor 5a793fe45c added consumption dataset 2020-04-02 17:43:24 +02:00
pvictor 528489fc15 updated synced charts vignette 2020-04-01 15:44:25 +02:00
505 changed files with 12810 additions and 40225 deletions

View File

@ -3,9 +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$

1
.github/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.html

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

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.4
Version: 0.4.3.9000
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,14 +24,12 @@ Imports:
shiny (>= 1.1.0)
Suggests:
testthat,
dplyr,
knitr,
scales,
rmarkdown,
gapminder,
highcharter
RoxygenNote: 7.1.0
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,23 +1,42 @@
# 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)
export(ax_labs)
export(ax_legend)
export(ax_markers)
export(ax_nodata)
export(ax_plotOptions)
export(ax_proxy_options)
export(ax_proxy_series)
@ -34,30 +53,74 @@ export(ax_xaxis)
export(ax_yaxis)
export(ax_yaxis2)
export(bar_opts)
export(boxplot_opts)
export(bubble_opts)
export(config_update)
export(events_opts)
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(run_input_demo)
export(renderApexfacet)
export(renderApexgrid)
export(renderSparkBox)
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)

114
NEWS.md
View File

@ -1,3 +1,117 @@
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
==================
* Updated ApexCharts.js to 3.18.1
* Support for candlestick charts in `apex()`.
* `apex()` has a new argument `synchronize` to easily synchronize charts together.
* `apex()` has new charts type: area-spline, area-step and step.
## 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 time-series charts.
* `add_hline()`, `add_vline()`, `add_point()` to add annotations on charts.
* `set_tooltip_fixed()` to fix tooltip in specific position.
## Bugfixes
* Xaxis datetime now display properly with columns and bars.
* Dark mode wasn't activated properly in `ax_theme()`.
apexcharter 0.1.4
==================

436
R/annotations.R Normal file
View File

@ -0,0 +1,436 @@
add_annotation <- function(ax, type_annotation = c("xaxis", "yaxis", "points"),
as_date = FALSE, position = "back", ...) {
type_annotation <- match.arg(type_annotation)
config <- dropNullsOrEmpty(list(...))
if (!is.null(config$label) && is.character(config$label)) {
config$label <- list(text = config$label)
}
if (!is.null(config$marker) && is.numeric(config$marker)) {
config$marker <- list(size = config$marker)
}
if (identical(type_annotation, "yaxis")) {
len <- length(config$y)
} else {
len <- length(config$x)
}
config <- rapply(
object = config,
f = rep_len,
length.out = len,
how = "replace"
)
extract <- function(el, index) {
`[`(el, index)
}
annotations <- lapply(
X = seq_len(len),
FUN = function(i) {
this <- rapply(
object = config,
f = extract,
index = i,
how = "list"
)
if (isTRUE(as_date)) {
if (!is.null(this$x))
this$x <- format_date(this$x)
if (!is.null(this$x2))
this$x2 <- format_date(this$x2)
}
this
}
)
if (identical(type_annotation, "xaxis")) {
if (!is.null(ax$x$ax_opts$annotations$xaxis)) {
annotations <- c(annotations, ax$x$ax_opts$annotations$xaxis)
ax$x$ax_opts$annotations$xaxis <- NULL
}
ax <- ax_annotations(
ax = ax,
position = position,
xaxis = annotations
)
} else if (identical(type_annotation, "yaxis")) {
if (!is.null(ax$x$ax_opts$annotations$yaxis)) {
annotations <- c(annotations, ax$x$ax_opts$annotations$yaxis)
ax$x$ax_opts$annotations$yaxis <- NULL
}
ax <- ax_annotations(
ax = ax,
position = position,
yaxis = annotations
)
} else if (identical(type_annotation, "points")) {
if (!is.null(ax$x$ax_opts$annotations$points)) {
annotations <- c(annotations, ax$x$ax_opts$annotations$points)
ax$x$ax_opts$annotations$points <- NULL
}
ax <- ax_annotations(
ax = ax,
position = position,
points = annotations
)
}
return(ax)
}
#' Label for annotations
#'
#' @param text Text for the annotation label.
#' @param borderColor Border color for the label.
#' @param borderWidth Border width for the label.
#' @param textAnchor The alignment of text relative to label's drawing position.
#' @param position Available options: left or right.
#' @param offsetX Sets the left offset for annotation label.
#' @param offsetY Sets the top offset for annotation label.
#' @param background Background Color for the annotation label.
#' @param color ForeColor for the annotation label.
#' @param fontSize FontSize for the annotation label.
#' @param fontWeight Font-weight for the annotation label.
#' @param fontFamily Font-family for the annotation label.
#' @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}}, \code{\link{add_point}},
#' \code{\link{add_event}}, \code{\link{add_event_marker}}.
#' @export
#'
label <- function(text = NULL,
borderColor = NULL,
borderWidth = NULL,
textAnchor = NULL,
position = NULL,
offsetX = NULL,
offsetY = NULL,
background = NULL,
color = NULL,
fontSize = NULL,
fontWeight = NULL,
fontFamily = NULL,
cssClass = NULL,
padding = c(2, 5, 2, 5)) {
dropNulls(list(
borderColor = borderColor,
borderWidth = borderWidth,
text = text,
textAnchor = textAnchor,
position = position,
offsetX = offsetX,
offsetY = offsetY,
style = dropNulls(list(
background = background,
color = color,
fontSize = fontSize,
fontWeight = fontWeight,
fontFamily = fontFamily,
padding = list(
top = padding[1],
right = padding[2],
bottom = padding[3],
left = padding[4]
)
))
))
}
#' Marker for annotations
#'
#' @param size Size of the marker.
#' @param fillColor Fill Color of the marker point.
#' @param strokeColor Stroke Color of the marker point.
#' @param strokeWidth Stroke Size of the marker point.
#' @param shape Shape of the marker: \code{"circle"} or \code{"square"}.
#' @param radius Radius of the marker (applies to square shape).
#' @param OffsetX Sets the left offset of the marker.
#' @param OffsetY Sets the top offset of the marker.
#' @param cssClass Additional CSS classes to append to the marker.
#'
#' @return A \code{list} that can be used in \code{\link{add_point}}.
#' @noRd
#'
marker <- function(size = NULL,
fillColor = NULL,
strokeColor = NULL,
strokeWidth = NULL,
shape = NULL,
radius = NULL,
OffsetX = NULL,
OffsetY = NULL,
cssClass = NULL) {
dropNulls(list(
size = size,
fillColor = fillColor,
strokeColor = strokeColor,
strokeWidth = strokeWidth,
shape = shape,
radius = radius,
OffsetX = OffsetX,
OffsetY = OffsetY,
cssClass = cssClass
))
}
#' @title Add a shaded area to a chart
#'
#' @description \code{add_shade()} allow to add a shaded area on specified range,
#' \code{add_shade_weekend()} add a shadow on every week-end.
#'
#' @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.
#' @param opacity Opacity of the shadow.
#' @param label Add a label to the shade, use a \code{character}
#' or see \code{\link{label}} for more controls.
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#' @note \code{add_shade_weekend} only works if variable
#' used for x-axis is of class \code{Date} or \code{POSIXt}.
#'
#'
#' @export
#'
#' @name add-shade
#'
#' @example examples/add_shade.R
add_shade <- function(ax, from, to, color = "#848484", opacity = 0.2, label = NULL, ...) {
if (length(from) != length(to)) {
stop("In add_shade: from and to must be of same length!", call. = FALSE)
}
add_annotation(
ax = ax,
type_annotation = "xaxis",
as_date = TRUE,
x = from,
x2 = to,
fillColor = color,
opacity = opacity,
label = label,
...
)
}
#' @export
#' @rdname add-shade
add_shade_weekend <- function(ax, color = "#848484", opacity = 0.2, label = NULL, ...) {
if (is.null(ax$x$xaxis)) {
stop("add_shade_weekend can only be used with apex().", call. = FALSE)
}
if (inherits(ax$x$xaxis$min, c("Date", "POSIXt"))) {
from <- as.Date(format(ax$x$xaxis$min, format = "%Y-%m-%d"))
to <- as.Date(format(ax$x$xaxis$max, format = "%Y-%m-%d"))
dates <- seq(from = from - 2, to = to + 2, by = "day")
if (inherits(ax$x$xaxis$min, "Date")) {
sat <- dates[format(dates, format = "%u") == 5]
time <- "12:00:00"
} else {
sat <- dates[format(dates, format = "%u") == 6]
time <- "00:00:00"
}
sun <- sat + 2
ax <- add_shade(
ax = ax,
from = paste(format(sat, format = "%Y-%m-%d"), time),
to = paste(format(sun, format = "%Y-%m-%d"), time),
color = color,
opacity = opacity,
label = label,
...
)
}
return(ax)
}
#' @title Add an event to a chart
#'
#' @description Add a vertical line to mark a special event on a chart.
#'
#' @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.
#' A higher number creates more space between dashes in the border.
#' Use \code{0} for plain line.
#' @param label Add a label to the shade, use a \code{character}
#' or see \code{\link{label}} for more controls.
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#'
#' @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, ...) {
add_annotation(
ax = ax,
type_annotation = "xaxis",
as_date = TRUE,
x = when,
borderColor = color,
strokeDashArray = dash,
label = label,
...
)
}
#' @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 [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,
size = 5,
color = "#000",
fill = "#FFF",
width = 2,
shape = "circle",
radius = 2,
label = NULL, ...) {
add_annotation(
ax = ax,
type_annotation = "points",
position = "front",
as_date = TRUE,
x = when, y = y,
marker = marker(
size = size,
fillColor = fill,
strokeColor = color,
strokeWidth = width,
shape = shape,
radius = radius
),
label = label,
...
)
}
#' Add horizontal or vertical line
#'
#' @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.
#' A higher number creates more space between dashes in the border.
#' Use \code{0} for plain line.
#' @param label Add a label to the shade, use a \code{character}
#' or see \code{\link{label}} for more controls.
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#'
#' @export
#'
#' @name add-vh-lines
#'
#' @example examples/add-lines.R
add_hline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
add_annotation(
ax = ax,
type_annotation = "yaxis",
position = "front",
as_date = FALSE,
y = value,
borderColor = color,
strokeDashArray = dash,
label = label,
...
)
}
#' @export
#' @rdname add-vh-lines
add_vline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
add_annotation(
ax = ax,
type_annotation = "xaxis",
position = "front",
as_date = FALSE,
x = value,
borderColor = color,
strokeDashArray = dash,
label = label,
...
)
}
#' Add an annotation point
#'
#' @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.
#' @param color Stroke Color of the marker point.
#' @param fill Fill Color of the marker point.
#' @param width Stroke Size of the marker point.
#' @param shape Shape of the marker: \code{"circle"} or \code{"square"}.
#' @param radius Radius of the marker (applies to square shape).
#' @param label Add a label to the shade, use a \code{character}
#' or see \code{\link{label}} for more controls.
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#'
#' @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,
size = 5,
color = "#000",
fill = "#FFF",
width = 2,
shape = "circle",
radius = 2,
label = NULL, ...) {
add_annotation(
ax = ax,
type_annotation = "points",
position = "front",
as_date = inherits(x, c("Date", "POSIXct")),
x = x, y = y,
marker = marker(
size = size,
fillColor = fill,
strokeColor = color,
strokeWidth = width,
shape = shape,
radius = radius
),
label = label,
...
)
}

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")
@ -350,3 +347,75 @@ pie_opts <- function(size = NULL,
)
}
#' @title Bubble options
#'
#' @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.
#' @param maxBubbleRadius Maximum radius size of a bubble.
#' If a bubble value is too large to cover the chart, this size will be used.
#' @param ... Additional parameters.
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/bubble/}.
#'
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#' @export
#'
#' @examples
#' apex(
#' data = mtcars,
#' type = "scatter",
#' mapping = aes(x = wt, y = mpg, z = qsec)
#' ) %>%
#' ax_plotOptions(
#' bubble = bubble_opts(
#' minBubbleRadius = 1,
#' maxBubbleRadius = 20
#' )
#' )
bubble_opts <- function(minBubbleRadius, maxBubbleRadius, ...) {
dropNulls(
list(
minBubbleRadius = minBubbleRadius,
maxBubbleRadius = 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,15 +125,18 @@ 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.
#' @param stackType When stacked, should the stacking be percentage based or normal stacking.
#' Available options: \code{"normal"} or \code{"100\%"}.
#' @param defaultLocale Locale to use : \code{"ca"}, \code{"de"}, \code{"el"}, \code{"en"}, \code{"es"}, \code{"fi"}, \code{"fr"},
#' \code{"hi"}, \code{"hr"}, \code{"hy"}, \code{"id"}, \code{"it"}, \code{"ko"}, \code{"nl"}, \code{"pt-br"},
#' \code{"ru"}, \code{"se"}, \code{"tr"}, \code{"ua"}.
#' @param defaultLocale Locale to use : \code{"ca"}, \code{"cs"}, \code{"de"},
#' \code{"el"}, \code{"en"}, \code{"es"}, \code{"fi"}, \code{"fr"}, \code{"he"},
#' \code{"hi"}, \code{"hr"}, \code{"hy"}, \code{"id"}, \code{"it"}, \code{"ko"},
#' \code{"lt"}, \code{"nb"}, \code{"nl"}, \code{"pl"}, \code{"pt-br"}, \code{"pt"},
#' \code{"ru"}, \code{"se"}, \code{"sk"}, \code{"sl"}, \code{"th"}, \code{"tr"},
#' \code{"ua"}.
#' @param locales Array of custom locales parameters.
#' @param animations A list of parameters.
#' @param background Background color for the chart area. If you want to set background with css, use \code{.apexcharts-canvas} to set it.
@ -151,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
@ -183,24 +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}}.
#' @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%")
@ -208,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(
@ -232,6 +234,8 @@ ax_plotOptions <- function(ax,
heatmap = NULL,
radialBar = NULL,
pie = NULL,
bubble = NULL,
boxPlot = NULL,
...) {
params <- c(as.list(environment()), list(...))[-1]
.ax_opt2(ax, "plotOptions", l = dropNulls(params))
@ -240,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, ...) {
@ -278,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"}.
@ -289,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,
@ -320,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..
@ -330,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",
@ -384,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.
@ -396,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)))
#'
@ -449,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
@ -485,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.
@ -511,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,
@ -560,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.
@ -574,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/}
@ -609,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
@ -618,7 +616,7 @@ ax_markers <- function(ax,
#' @param style
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @noRd
#'
ax_noData <- function(ax,
@ -636,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") %>%
@ -677,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
@ -720,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(
@ -760,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.
@ -770,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/}
@ -801,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.
@ -811,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/}
@ -845,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)
@ -859,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/}
@ -901,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.
@ -919,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)
#'
@ -976,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.
@ -995,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))
#'
@ -1082,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.
@ -1097,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/}
@ -1151,25 +1145,13 @@ 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
#'
#' @examples
#'
#' library(dplyr)
#' data("economics_long", package = "ggplot2")
#'
#' eco <- economics_long %>%
#' filter(variable %in% c("pce", "pop")) %>%
#' filter(date >= "2000-01-01")
#'
#' apex(eco, aes(x = date, y = value, color = variable), type = "line") %>%
#' ax_yaxis(title = list(text = "Pce")) %>%
#' ax_yaxis2(opposite = TRUE, title = list(text = "Pop"))
#'
#' @example examples/ax_yaxis2.R
ax_yaxis2 <- function(ax, ...) {
params <- dropNulls(list(...))
yaxis <- .get_ax_opt(ax, "yaxis")
@ -1188,40 +1170,38 @@ ax_yaxis2 <- function(ax, ...) {
#' Theme for charts
#'
#' @param ax A \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 A \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,
@ -1234,6 +1214,105 @@ ax_theme <- function(ax,
mode = mode,
palette = palette,
monochrome = monochrome
), list(...))[-1]
), list(...))
.ax_opt2(ax, "theme", l = dropNulls(params))
}
#' Configuration for charts with no data
#'
#' @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"}.
#' @param color ForeColor of the text.
#' @param fontSize FontSize of the text.
#' @param fontFamily FontFamily of the text.
#' @param offsetX,offsetY Text offset.
#'
#' @export
#'
#' @examples
#' empty <- data.frame(
#' var1 = character(0),
#' var2 = numeric(0)
#' )
#' apex(empty, aes(var1, var2), "column") %>%
#' ax_nodata(
#' text = "Sorry no data to visualize",
#' fontSize = "30px"
#' )
ax_nodata <- function(ax,
text = "No data",
align = "center",
verticalAlign = "middle",
color = NULL,
fontSize = NULL,
fontFamily = NULL,
offsetX = NULL,
offsetY = NULL) {
params <- list(
text = text,
align = align,
verticalAlign = verticalAlign,
offsetX = offsetX,
offsetY = offsetY,
style = dropNulls(list(
color = color,
fontSize = fontSize,
fontFamily = fontFamily
))
)
.ax_opt2(ax, "noData", l = dropNulls(params))
}
#' 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))
}

323
R/apex.R
View File

@ -1,56 +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{"area"}, \code{"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, elementId = NULL) {
width = NULL,
height = NULL,
elementId = NULL) {
type <- match.arg(
arg = type,
arg = type,
choices = c(
"column", "bar", "line", "area", "spline", "area-spline",
"pie", "donut", "radialBar", "radar", "scatter", "heatmap",
"timeline"
"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),
@ -58,48 +81,106 @@ apex <- function(data, mapping, type = "column", ...,
)
} else {
opts <- list(
chart = list(type = correct_type(type)),
chart = dropNulls(list(
type = correct_type(type),
group = synchronize
)),
series = make_series(mapdata, mapping, type, serie_name)
)
}
if (!is.null(synchronize)) {
opts$yaxis$labels$minWidth <- 15
}
opts <- modifyList(opts, choose_config(type, mapdata))
apexchart(
ax_opts = opts,
width = width, height = height,
elementId = elementId,
if (isTRUE(getOption("apex.axis.light", default = TRUE))) {
opts$yaxis$labels$style$colors <- "#848484"
opts$xaxis$labels$style$colors <- "#848484"
}
ax <- apexchart(
ax_opts = opts,
width = width,
height = height,
elementId = elementId,
auto_update = auto_update
)
if (inherits(mapdata$x, c("character", "Date", "POSIXt", "numeric", "integer")) & length(mapdata$x) > 0) {
ax$x$xaxis <- list(
min = min(mapdata$x, na.rm = TRUE),
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, "timeline")) {
#' @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 (isTRUE(type %in% c("rangeBar", "timeline"))) {
if (!all(c("x", "start", "end") %in% names(mapping)))
stop("For timeline charts 'x', 'start', and 'end' aesthetice must be provided.", call. = FALSE)
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(list(
name = serie_name,
series <- list(dropNulls(list(
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)
if (length(unique(len_grp)) > 1) {
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.")
}
series <- lapply(
@ -107,14 +188,15 @@ 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]
list(
name = x,
data <- data[order(match(x = data[["x"]], table = x_order, nomatch = 0L)), , drop = FALSE]
dropNulls(list(
name = as.character(x),
type = multi_type(type),
data = parse_df(
data = data,
data = data,
add_names = add_names
)
)
))
}
)
}
@ -130,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) {
@ -171,26 +256,67 @@ 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 (identical(type, "spline")) {
} else if (isTRUE(type %in% c("spline", "step", "slope"))) {
"line"
} else if (identical(type, "timeline")) {
} else if (isTRUE(type %in% c("area-spline", "area-step"))) {
"area"
} else if (isTRUE(type %in% c("timeline", "dumbbell"))) {
"rangeBar"
} else if (identical(type, "boxplot")) {
"boxPlot"
} else {
type
}
}
range_num <- function(x) {
if (is.numeric(x)) {
range(pretty(x))
multi_type <- function(x) {
multis <- c("column", "area", "line",
"spline", "step", "scatter",
"bubble", "rangeArea")
if (isTRUE(x %in% multis)) {
correct_type(x)
} else {
NULL
}
}
range_num <- function(x) {
if (is.numeric(x) & length(x) > 0) {
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
@ -198,38 +324,54 @@ 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),
"column" = config_bar(horizontal = FALSE),
"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),
"scatter" = config_scatter(range_x = range_x, range_y = range_y),
"bubble" = config_scatter(range_x = range_x, range_y = range_y),
"step" = config_line(curve = "stepline", datetime = datetime),
"area-spline" = config_line(curve = "smooth", datetime = datetime),
"area-step" = config_line(curve = "stepline", datetime = datetime),
"scatter" = config_scatter(range_x = range_x, range_y = range_y, datetime = datetime),
"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) {
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,
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"
}
config
}
@ -241,6 +383,9 @@ config_line <- function(curve = "straight", datetime = FALSE) {
stroke = list(
curve = curve,
width = 2
),
yaxis = list(
decimalsInFloat = 2
)
)
if (isTRUE(datetime)) {
@ -252,15 +397,28 @@ config_line <- function(curve = "straight", datetime = FALSE) {
}
config_scatter <- function(range_x, range_y) {
config_scatter <- function(range_x, range_y, datetime = FALSE) {
config <- list(
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]
min = range_y$range[1],
max = range_y$range[2],
tickAmount = range_y$n,
labels = list(formatter = format_num("~r")),
tooltip = list(
enabled = TRUE
)
),
grid = list(
xaxis = list(
@ -270,6 +428,10 @@ config_scatter <- function(range_x, range_y) {
)
)
)
if (isTRUE(datetime)) {
config$xaxis$type <- "datetime"
}
config
}
config_timeline <- function() {
@ -285,3 +447,30 @@ config_timeline <- function() {
)
}
config_candlestick <- function() {
list(
xaxis = list(
type = "datetime"
)
)
}
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,29 +1,34 @@
#' 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()
}
x <- list(
ax_opts = ax_opts,
auto_update = auto_update
auto_update = auto_update,
sparkbox = FALSE
)
# create widget
@ -34,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%",
@ -51,14 +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", "de", "el", "en", "es", "fi", "fr", "hi", "hr", "hy",
"id", "it", "ko", "nl", "pt-br", "ru", "se", "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(
@ -67,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)
@ -85,20 +98,24 @@ 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
#' is re-rendered from the existing paths
#'
#' 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,
options_redrawPaths = FALSE) {
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,
options_redrawPaths = options_redrawPaths
series_animate = series_animate,
update_options = update_options,
options_animate = options_animate,
options_redrawPaths = options_redrawPaths,
update_synced_charts = update_synced_charts
)
}
@ -108,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)
}

107
R/data.R
View File

@ -1,33 +1,100 @@
#' 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 on 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
#'
#' The dataset contains data about UNHCR's populations of concern summarised by continent of origin.
#'
#' @format A data frame with 913 observations on the following 4 variables.
#' @format A data frame with 913 observations and the following 4 variables:
#' \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"
#' Electricity consumption and forecasting
#'
#' Electricity consumption per day in France for january and february of year 2020.
#'
#' @format A data frame with 120 observations and the following 3 variables:
#' \describe{
#' \item{\code{date}}{date.}
#' \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/})
"consumption"
#' Candlestick demo data
#'
#'
#' @format A data frame with 60 observations and the following 5 variables:
#' \describe{
#' \item{\code{datetime}}{Timestamp.}
#' \item{\code{open}}{Open value.}
#' \item{\code{high}}{Highest value.}
#' \item{\code{low}}{Lowest value.}
#' \item{\code{close}}{Close value.}
#' }
#' @source Apexcharts (\url{https://apexcharts.com/javascript-chart-demos/candlestick-charts/basic/})
"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.
@ -25,16 +25,30 @@
#' )
ax_labs <- function(ax, title = NULL, subtitle = NULL, x = NULL, y = NULL) {
if (!is.null(title)) {
ax <- ax_title(ax = ax, text = title)
ax <- ax_title(
ax = ax,
text = title,
style = list(fontWeight = 700, fontSize = "16px")
)
}
if (!is.null(subtitle)) {
ax <- ax_subtitle(ax = ax, text = subtitle)
ax <- ax_subtitle(
ax = ax,
text = subtitle,
style = list(fontWeight = 400, fontSize = "14px")
)
}
if (!is.null(x)) {
ax <- ax_xaxis(ax = ax, title = list(text = x))
ax <- ax_xaxis(
ax = ax,
title = list(text = x, style = list(fontWeight = 400, fontSize = "14px"))
)
}
if (!is.null(y)) {
ax <- ax_yaxis(ax = ax, title = list(text = y))
ax <- ax_yaxis(
ax = ax,
title = list(text = y, style = list(fontWeight = 400, fontSize = "14px"))
)
}
ax
}

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)
@ -68,6 +68,8 @@ parse_df <- function(data, add_names = FALSE) {
#' @importFrom htmlwidgets JS
js_date <- function(x) {
if (inherits(x, "POSIXt"))
x <- format(x, format = "%Y-%m-%d %H:%M:%S")
lapply(sprintf("new Date('%s').getTime()", x), JS)
}
@ -108,4 +110,85 @@ 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 = as.numeric(val$x) * 1000,
y = c(val$open, val$high, val$low, val$close)
)
}
)
))
}
#' @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,24 +174,54 @@ 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.
#'
#' @export
#'
#' @importFrom shiny shinyAppFile
#'
#' @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")
)
}
@ -194,6 +229,43 @@ run_input_demo <- function(example = c("click", "zoom", "selection")) {
#' Run Shiny synchronization example
#'
#' @export
#'
#' @importFrom shiny shinyAppFile
#'
#' @examples
#' if (interactive()) {
#'
#' run_demo_sync()
#'
#' }
run_demo_sync <- function() {
shiny::shinyAppFile(
appFile = system.file("examples/sync", "app.R", package = "apexcharter"),
options = list("display.mode" = "showcase")
)
}
#' Run Shiny spark boxes example
#'
#' @export
#'
#' @importFrom shiny shinyAppFile
#'
#' @examples
#' if (interactive()) {
#'
#' run_demo_sparkbox()
#'
#' }
run_demo_sparkbox <- function() {
shiny::shinyAppFile(
appFile = system.file("examples/spark", "app.R", package = "apexcharter"),
options = list("display.mode" = "showcase")
)
}
# nocov end

116
R/spark-box.R Normal file
View File

@ -0,0 +1,116 @@
#' Create a box with a sparkline
#'
#' @param data A \code{data.frame}-like object with at least two columns,
#' first is mapped to x-axis, second to y-axis.
#' @param title Title to display in the box.
#' @param subtitle Subtitle to display in the box.
#' @param color Color of the chart.
#' @param background Background color of the box.
#' @param type Type of chart, currently type supported are :
#' \code{"area"} (default), \code{"line"}, \code{"spline"}, \code{"column"}.
#' @param synchronize Give a common id to charts to synchronize them (tooltip and zoom).
#' @param title_style,subtitle_style A \code{list} of named attributes to style
#' the title / subtitle, possible values are \code{fontSize},
#' \code{fontWeight}, \code{fontFamily}, \code{color}.
#' @param width,height A numeric input in pixels.
#' @param elementId Use an explicit element ID for the widget.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @note In Shiny use \code{sparkBoxOutput} / \code{renderSparkBox} to render boxes, see example.
#' Boxes have CSS class \code{"apexcharter-spark-box"} if you need more styling.
#'
#' @importFrom htmlwidgets sizingPolicy
#' @importFrom rlang sym
#' @importFrom ggplot2 aes
#'
#' @example examples/spark_box.R
spark_box <- function(data,
title = NULL,
subtitle = NULL,
color = "#2E93fA",
background = "#FFF",
type = c("area", "line", "spline", "column"),
synchronize = NULL,
title_style = NULL,
subtitle_style = NULL,
width = NULL,
height = NULL,
elementId = NULL) {
type <- match.arg(type)
data <- as.data.frame(data)
if (ncol(data) < 2)
stop("'data' must have at least two columns!", call. = FALSE)
x_var <- names(data)[1]
y_var <- names(data)[2]
spark <- apex(
data = data,
aes(x = !!sym(x_var), y = !!sym(y_var)),
type = type,
auto_update = config_update(update_options = TRUE)
)
spark <- ax_chart(
ax = spark,
sparkline = list(enabled = TRUE),
group = synchronize
)
spark <- ax_yaxis(spark, show = FALSE)
spark <- ax_colors(spark, color)
if (!is.null(title)) {
if (is.null(title_style))
title_style <- list(fontSize = "24px")
if (is.null(title_style$fontSize))
title_style$fontSize <- "24px"
spark <- ax_title(
ax = spark,
text = title,
style = title_style
)
}
if (!is.null(subtitle)) {
if (is.null(subtitle_style))
subtitle_style <- list(fontSize = "14px")
if (is.null(subtitle_style$fontSize))
subtitle_style$fontSize <- "14px"
spark <- ax_subtitle(
ax = spark,
text = subtitle,
style = subtitle_style
)
}
spark$x$sparkbox <- list(
color = color, background = background
)
spark$sizingPolicy <- htmlwidgets::sizingPolicy(
defaultWidth = "100%",
defaultHeight = "160px",
viewer.defaultHeight = "160px",
viewer.defaultWidth = "100%",
viewer.fill = FALSE,
knitr.figure = FALSE,
knitr.defaultWidth = "100%",
knitr.defaultHeight = "160px",
browser.fill = FALSE,
viewer.suppress = FALSE,
browser.external = TRUE,
padding = 15
)
return(spark)
}
#' @rdname apexcharter-shiny
#' @export
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) { # nocov start
if (!quoted) { expr <- substitute(expr) } # force quoted
htmlwidgets::shinyRenderWidget(expr, apexchartOutput, env, quoted = TRUE)
} # nocov end

22
R/tooltip.R Normal file
View File

@ -0,0 +1,22 @@
#' Fixed tooltip
#'
#' @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.
#'
#' @export
#'
#' @example examples/set_tooltip_fixed.R
set_tooltip_fixed <- function(ax,
position = c("topLeft", "topRight", "bottomLeft", "bottomRight"),
offsetX = NULL,
offsetY = NULL) {
position <- match.arg(position)
ax_tooltip(ax = ax, fixed = list(
enabled = TRUE, position = position,
offsetX = offsetX, offsetY = offsetY
))
}

View File

@ -1,12 +1,18 @@
# dropNulls
dropNulls <- function(x) {
x[!vapply(x, is.null, FUN.VALUE = logical(1))]
null_or_empty <- function(x) {
is.null(x) || length(x) == 0
}
`%||%` <- function(x, y) {
if (!is.null(x)) x else y
dropNullsOrEmpty <- function(x) {
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))]
}
formatNoSci <- function(x) {
@ -35,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)
}
@ -93,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,32 +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)
[![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")
```
@ -38,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)
@ -64,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") %>%
@ -83,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")
```
@ -145,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,6 +1,17 @@
url: https://dreamrs.github.io/apexcharter/
template:
package: dreamRs
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

37
data-raw/candlestick.R Normal file
View File

@ -0,0 +1,37 @@
# ------------------------------------------------------------------------
#
# Title : Candlestick data
# By : Victor
# Date : 2020-06-13
#
# ------------------------------------------------------------------------
library(jsonlite)
cdle <- read_json(path = "data-raw/candlestick.json")
cdle <- lapply(
X = cdle,
FUN = function(x) {
data.frame(
datetime = x$x,
open = x$y[[1]],
high = x$y[[2]],
low = x$y[[3]],
close = x$y[[4]],
stringsAsFactors = FALSE
)
}
)
cdle <- do.call(rbind, cdle)
cdle$datetime <- as.POSIXct(cdle$datetime, format = "%Y-%m-%dT%H:%M:%S", tz = "UTC")
cdle
apex(cdle, aes(x = datetime, open = open, close = close, low = low, high = high), type = "candlestick")
candles <- as.data.frame(cdle)
usethis::use_data(candles, overwrite = TRUE)

View File

@ -0,0 +1 @@
[{"x":"2018-10-05T22:30:00.000Z","y":[6629.81,6650.5,6623.04,6633.33]},{"x":"2018-10-05T23:00:00.000Z","y":[6632.01,6643.59,6620,6630.11]},{"x":"2018-10-05T23:30:00.000Z","y":[6630.71,6648.95,6623.34,6635.65]},{"x":"2018-10-06T00:00:00.000Z","y":[6635.65,6651,6629.67,6638.24]},{"x":"2018-10-06T00:30:00.000Z","y":[6638.24,6640,6620,6624.47]},{"x":"2018-10-06T01:00:00.000Z","y":[6624.53,6636.03,6621.68,6624.31]},{"x":"2018-10-06T01:30:00.000Z","y":[6624.61,6632.2,6617,6626.02]},{"x":"2018-10-06T02:00:00.000Z","y":[6627,6627.62,6584.22,6603.02]},{"x":"2018-10-06T02:30:00.000Z","y":[6605,6608.03,6598.95,6604.01]},{"x":"2018-10-06T03:00:00.000Z","y":[6604.5,6614.4,6602.26,6608.02]},{"x":"2018-10-06T03:30:00.000Z","y":[6608.02,6610.68,6601.99,6608.91]},{"x":"2018-10-06T04:00:00.000Z","y":[6608.91,6618.99,6608.01,6612]},{"x":"2018-10-06T04:30:00.000Z","y":[6612,6615.13,6605.09,6612]},{"x":"2018-10-06T05:00:00.000Z","y":[6612,6624.12,6608.43,6622.95]},{"x":"2018-10-06T05:30:00.000Z","y":[6623.91,6623.91,6615,6615.67]},{"x":"2018-10-06T06:00:00.000Z","y":[6618.69,6618.74,6610,6610.4]},{"x":"2018-10-06T06:30:00.000Z","y":[6611,6622.78,6610.4,6614.9]},{"x":"2018-10-06T07:00:00.000Z","y":[6614.9,6626.2,6613.33,6623.45]},{"x":"2018-10-06T07:30:00.000Z","y":[6623.48,6627,6618.38,6620.35]},{"x":"2018-10-06T08:00:00.000Z","y":[6619.43,6620.35,6610.05,6615.53]},{"x":"2018-10-06T08:30:00.000Z","y":[6615.53,6617.93,6610,6615.19]},{"x":"2018-10-06T09:00:00.000Z","y":[6615.19,6621.6,6608.2,6620]},{"x":"2018-10-06T09:30:00.000Z","y":[6619.54,6625.17,6614.15,6620]},{"x":"2018-10-06T10:00:00.000Z","y":[6620.33,6634.15,6617.24,6624.61]},{"x":"2018-10-06T10:30:00.000Z","y":[6625.95,6626,6611.66,6617.58]},{"x":"2018-10-06T11:00:00.000Z","y":[6619,6625.97,6595.27,6598.86]},{"x":"2018-10-06T11:30:00.000Z","y":[6598.86,6598.88,6570,6587.16]},{"x":"2018-10-06T12:00:00.000Z","y":[6588.86,6600,6580,6593.4]},{"x":"2018-10-06T12:30:00.000Z","y":[6593.99,6598.89,6585,6587.81]},{"x":"2018-10-06T13:00:00.000Z","y":[6587.81,6592.73,6567.14,6578]},{"x":"2018-10-06T13:30:00.000Z","y":[6578.35,6581.72,6567.39,6579]},{"x":"2018-10-06T14:00:00.000Z","y":[6579.38,6580.92,6566.77,6575.96]},{"x":"2018-10-06T14:30:00.000Z","y":[6575.96,6589,6571.77,6588.92]},{"x":"2018-10-06T15:00:00.000Z","y":[6588.92,6594,6577.55,6589.22]},{"x":"2018-10-06T15:30:00.000Z","y":[6589.3,6598.89,6589.1,6596.08]},{"x":"2018-10-06T16:00:00.000Z","y":[6597.5,6600,6588.39,6596.25]},{"x":"2018-10-06T16:30:00.000Z","y":[6598.03,6600,6588.73,6595.97]},{"x":"2018-10-06T17:00:00.000Z","y":[6595.97,6602.01,6588.17,6602]},{"x":"2018-10-06T17:30:00.000Z","y":[6602,6607,6596.51,6599.95]},{"x":"2018-10-06T18:00:00.000Z","y":[6600.63,6601.21,6590.39,6591.02]},{"x":"2018-10-06T18:30:00.000Z","y":[6591.02,6603.08,6591,6591]},{"x":"2018-10-06T19:00:00.000Z","y":[6591,6601.32,6585,6592]},{"x":"2018-10-06T19:30:00.000Z","y":[6593.13,6596.01,6590,6593.34]},{"x":"2018-10-06T20:00:00.000Z","y":[6593.34,6604.76,6582.63,6593.86]},{"x":"2018-10-06T20:30:00.000Z","y":[6593.86,6604.28,6586.57,6600.01]},{"x":"2018-10-06T21:00:00.000Z","y":[6601.81,6603.21,6592.78,6596.25]},{"x":"2018-10-06T21:30:00.000Z","y":[6596.25,6604.2,6590,6602.99]},{"x":"2018-10-06T22:00:00.000Z","y":[6602.99,6606,6584.99,6587.81]},{"x":"2018-10-06T22:30:00.000Z","y":[6587.81,6595,6583.27,6591.96]},{"x":"2018-10-06T23:00:00.000Z","y":[6591.97,6596.07,6585,6588.39]},{"x":"2018-10-06T23:30:00.000Z","y":[6587.6,6598.21,6587.6,6594.27]},{"x":"2018-10-07T00:00:00.000Z","y":[6596.44,6601,6590,6596.55]},{"x":"2018-10-07T00:30:00.000Z","y":[6598.91,6605,6596.61,6600.02]},{"x":"2018-10-07T01:00:00.000Z","y":[6600.55,6605,6589.14,6593.01]},{"x":"2018-10-07T01:30:00.000Z","y":[6593.15,6605,6592,6603.06]},{"x":"2018-10-07T02:00:00.000Z","y":[6603.07,6604.5,6599.09,6603.89]},{"x":"2018-10-07T02:30:00.000Z","y":[6604.44,6604.44,6600,6603.5]},{"x":"2018-10-07T03:00:00.000Z","y":[6603.5,6603.99,6597.5,6603.86]},{"x":"2018-10-07T03:30:00.000Z","y":[6603.85,6605,6600,6604.07]},{"x":"2018-10-07T04:00:00.000Z","y":[6604.98,6606,6604.07,6606]}]

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"
)

50
data-raw/elec-data.R Normal file
View File

@ -0,0 +1,50 @@
## code to prepare `elec-data` dataset goes here
# Packages ----------------------------------------------------------------
library(data.table)
library(lubridate)
library(rte.data)
library(apexcharter)
# Consumption & forecast --------------------------------------------------
consumption <- get_consumption(
resource = "short_term",
type = c("REALISED", "D-1"),
start_date = "2020-01-01",
end_date = "2020-03-01"
)
apex(consumption, aes(start_date, value, group = type), "line")
consumption <- consumption[, list(value = round(sum(value) / 4000)), by = list(date = as_date(start_date), type)]
consumption[type == "REALISED", type := "Realised"]
consumption[type == "D-1", type := "Forecast D-1"]
apex(consumption, aes(date, value, group = type), "line")
consumption <- as.data.frame(consumption)
usethis::use_data(consumption, overwrite = TRUE)
# Actual generation -------------------------------------------------------
actual_generation <- get_actual_generation(
resource = "actual_generations_per_production_type",
start_date = "2017-06-12",
end_date = "2017-06-13"
)

View File

@ -0,0 +1,70 @@
# 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_long[, lifeExp := round(lifeExp, 1)]
life_expec <- dcast(life_expec_long, country ~ year, value.var = "lifeExp")
life_expec[, type := fifelse(`1972` > `2007`, "decreased", "increased")]
life_expec_long <- melt(data = life_expec, id.vars = c("country", "type"), variable.name = "year", value.name = "lifeExp")
# 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/candles.rda Normal file

Binary file not shown.

BIN
data/climate_paris.rda Normal file

Binary file not shown.

BIN
data/consumption.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,229 +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.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<link href="css/theme.css" rel="stylesheet">
<!-- Font -->
<link href="css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- Particles -->
<script src="js/particles.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></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.3.990</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.3.990</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/labs.html">Labs: title, subtitle &amp; axis</a>
</li>
<li>
<a href="articles/lines.html">Options &amp; styles for lines</a>
</li>
<li>
<a href="articles/shiny-integration.html">Shiny integration</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.4.1.</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,231 +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.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<link href="css/theme.css" rel="stylesheet">
<!-- Font -->
<link href="css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- Particles -->
<script src="js/particles.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></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.3.990</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.3.990</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/labs.html">Labs: title, subtitle &amp; axis</a>
</li>
<li>
<a href="articles/lines.html">Options &amp; styles for lines</a>
</li>
<li>
<a href="articles/shiny-integration.html">Shiny integration</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.4.1.</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);
}
});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,903 +0,0 @@
(function() {
// If window.HTMLWidgets is already defined, then use it; otherwise create a
// new object. This allows preceding code to set options that affect the
// initialization process (though none currently exist).
window.HTMLWidgets = window.HTMLWidgets || {};
// See if we're running in a viewer pane. If not, we're in a web browser.
var viewerMode = window.HTMLWidgets.viewerMode =
/\bviewer_pane=1\b/.test(window.location);
// See if we're running in Shiny mode. If not, it's a static document.
// Note that static widgets can appear in both Shiny and static modes, but
// obviously, Shiny widgets can only appear in Shiny apps/documents.
var shinyMode = window.HTMLWidgets.shinyMode =
typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
// We can't count on jQuery being available, so we implement our own
// version if necessary.
function querySelectorAll(scope, selector) {
if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
return scope.find(selector);
}
if (scope.querySelectorAll) {
return scope.querySelectorAll(selector);
}
}
function asArray(value) {
if (value === null)
return [];
if ($.isArray(value))
return value;
return [value];
}
// Implement jQuery's extend
function extend(target /*, ... */) {
if (arguments.length == 1) {
return target;
}
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
// IE8 doesn't support Array.forEach.
function forEach(values, callback, thisArg) {
if (values.forEach) {
values.forEach(callback, thisArg);
} else {
for (var i = 0; i < values.length; i++) {
callback.call(thisArg, values[i], i, values);
}
}
}
// Replaces the specified method with the return value of funcSource.
//
// Note that funcSource should not BE the new method, it should be a function
// that RETURNS the new method. funcSource receives a single argument that is
// the overridden method, it can be called from the new method. The overridden
// method can be called like a regular function, it has the target permanently
// bound to it so "this" will work correctly.
function overrideMethod(target, methodName, funcSource) {
var superFunc = target[methodName] || function() {};
var superFuncBound = function() {
return superFunc.apply(target, arguments);
};
target[methodName] = funcSource(superFuncBound);
}
// Add a method to delegator that, when invoked, calls
// delegatee.methodName. If there is no such method on
// the delegatee, but there was one on delegator before
// delegateMethod was called, then the original version
// is invoked instead.
// For example:
//
// var a = {
// method1: function() { console.log('a1'); }
// method2: function() { console.log('a2'); }
// };
// var b = {
// method1: function() { console.log('b1'); }
// };
// delegateMethod(a, b, "method1");
// delegateMethod(a, b, "method2");
// a.method1();
// a.method2();
//
// The output would be "b1", "a2".
function delegateMethod(delegator, delegatee, methodName) {
var inherited = delegator[methodName];
delegator[methodName] = function() {
var target = delegatee;
var method = delegatee[methodName];
// The method doesn't exist on the delegatee. Instead,
// call the method on the delegator, if it exists.
if (!method) {
target = delegator;
method = inherited;
}
if (method) {
return method.apply(target, arguments);
}
};
}
// Implement a vague facsimilie of jQuery's data method
function elementData(el, name, value) {
if (arguments.length == 2) {
return el["htmlwidget_data_" + name];
} else if (arguments.length == 3) {
el["htmlwidget_data_" + name] = value;
return el;
} else {
throw new Error("Wrong number of arguments for elementData: " +
arguments.length);
}
}
// http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function hasClass(el, className) {
var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
return re.test(el.className);
}
// elements - array (or array-like object) of HTML elements
// className - class name to test for
// include - if true, only return elements with given className;
// if false, only return elements *without* given className
function filterByClass(elements, className, include) {
var results = [];
for (var i = 0; i < elements.length; i++) {
if (hasClass(elements[i], className) == include)
results.push(elements[i]);
}
return results;
}
function on(obj, eventName, func) {
if (obj.addEventListener) {
obj.addEventListener(eventName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(eventName, func);
}
}
function off(obj, eventName, func) {
if (obj.removeEventListener)
obj.removeEventListener(eventName, func, false);
else if (obj.detachEvent) {
obj.detachEvent(eventName, func);
}
}
// Translate array of values to top/right/bottom/left, as usual with
// the "padding" CSS property
// https://developer.mozilla.org/en-US/docs/Web/CSS/padding
function unpackPadding(value) {
if (typeof(value) === "number")
value = [value];
if (value.length === 1) {
return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
}
if (value.length === 2) {
return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
}
if (value.length === 3) {
return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
}
if (value.length === 4) {
return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
}
}
// Convert an unpacked padding object to a CSS value
function paddingToCss(paddingObj) {
return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
}
// Makes a number suitable for CSS
function px(x) {
if (typeof(x) === "number")
return x + "px";
else
return x;
}
// Retrieves runtime widget sizing information for an element.
// The return value is either null, or an object with fill, padding,
// defaultWidth, defaultHeight fields.
function sizingPolicy(el) {
var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
if (!sizingEl)
return null;
var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
if (viewerMode) {
return sp.viewer;
} else {
return sp.browser;
}
}
// @param tasks Array of strings (or falsy value, in which case no-op).
// Each element must be a valid JavaScript expression that yields a
// function. Or, can be an array of objects with "code" and "data"
// properties; in this case, the "code" property should be a string
// of JS that's an expr that yields a function, and "data" should be
// an object that will be added as an additional argument when that
// function is called.
// @param target The object that will be "this" for each function
// execution.
// @param args Array of arguments to be passed to the functions. (The
// same arguments will be passed to all functions.)
function evalAndRun(tasks, target, args) {
if (tasks) {
forEach(tasks, function(task) {
var theseArgs = args;
if (typeof(task) === "object") {
theseArgs = theseArgs.concat([task.data]);
task = task.code;
}
var taskFunc = tryEval(task);
if (typeof(taskFunc) !== "function") {
throw new Error("Task must be a function! Source:\n" + task);
}
taskFunc.apply(target, theseArgs);
});
}
}
// Attempt eval() both with and without enclosing in parentheses.
// Note that enclosing coerces a function declaration into
// an expression that eval() can parse
// (otherwise, a SyntaxError is thrown)
function tryEval(code) {
var result = null;
try {
result = eval(code);
} catch(error) {
if (!error instanceof SyntaxError) {
throw error;
}
try {
result = eval("(" + code + ")");
} catch(e) {
if (e instanceof SyntaxError) {
throw error;
} else {
throw e;
}
}
}
return result;
}
function initSizing(el) {
var sizing = sizingPolicy(el);
if (!sizing)
return;
var cel = document.getElementById("htmlwidget_container");
if (!cel)
return;
if (typeof(sizing.padding) !== "undefined") {
document.body.style.margin = "0";
document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
}
if (sizing.fill) {
document.body.style.overflow = "hidden";
document.body.style.width = "100%";
document.body.style.height = "100%";
document.documentElement.style.width = "100%";
document.documentElement.style.height = "100%";
if (cel) {
cel.style.position = "absolute";
var pad = unpackPadding(sizing.padding);
cel.style.top = pad.top + "px";
cel.style.right = pad.right + "px";
cel.style.bottom = pad.bottom + "px";
cel.style.left = pad.left + "px";
el.style.width = "100%";
el.style.height = "100%";
}
return {
getWidth: function() { return cel.offsetWidth; },
getHeight: function() { return cel.offsetHeight; }
};
} else {
el.style.width = px(sizing.width);
el.style.height = px(sizing.height);
return {
getWidth: function() { return el.offsetWidth; },
getHeight: function() { return el.offsetHeight; }
};
}
}
// Default implementations for methods
var defaults = {
find: function(scope) {
return querySelectorAll(scope, "." + this.name);
},
renderError: function(el, err) {
var $el = $(el);
this.clearError(el);
// Add all these error classes, as Shiny does
var errClass = "shiny-output-error";
if (err.type !== null) {
// use the classes of the error condition as CSS class names
errClass = errClass + " " + $.map(asArray(err.type), function(type) {
return errClass + "-" + type;
}).join(" ");
}
errClass = errClass + " htmlwidgets-error";
// Is el inline or block? If inline or inline-block, just display:none it
// and add an inline error.
var display = $el.css("display");
$el.data("restore-display-mode", display);
if (display === "inline" || display === "inline-block") {
$el.hide();
if (err.message !== "") {
var errorSpan = $("<span>").addClass(errClass);
errorSpan.text(err.message);
$el.after(errorSpan);
}
} else if (display === "block") {
// If block, add an error just after the el, set visibility:none on the
// el, and position the error to be on top of the el.
// Mark it with a unique ID and CSS class so we can remove it later.
$el.css("visibility", "hidden");
if (err.message !== "") {
var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
// setting width can push out the page size, forcing otherwise
// unnecessary scrollbars to appear and making it impossible for
// the element to shrink; so use max-width instead
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
errorDiv.text(err.message);
$el.after(errorDiv);
// Really dumb way to keep the size/position of the error in sync with
// the parent element as the window is resized or whatever.
var intId = setInterval(function() {
if (!errorDiv[0].parentElement) {
clearInterval(intId);
return;
}
errorDiv
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
}, 500);
}
}
},
clearError: function(el) {
var $el = $(el);
var display = $el.data("restore-display-mode");
$el.data("restore-display-mode", null);
if (display === "inline" || display === "inline-block") {
if (display)
$el.css("display", display);
$(el.nextSibling).filter(".htmlwidgets-error").remove();
} else if (display === "block"){
$el.css("visibility", "inherit");
$(el.nextSibling).filter(".htmlwidgets-error").remove();
}
},
sizing: {}
};
// Called by widget bindings to register a new type of widget. The definition
// object can contain the following properties:
// - name (required) - A string indicating the binding name, which will be
// used by default as the CSS classname to look for.
// - initialize (optional) - A function(el) that will be called once per
// widget element; if a value is returned, it will be passed as the third
// value to renderValue.
// - renderValue (required) - A function(el, data, initValue) that will be
// called with data. Static contexts will cause this to be called once per
// element; Shiny apps will cause this to be called multiple times per
// element, as the data changes.
window.HTMLWidgets.widget = function(definition) {
if (!definition.name) {
throw new Error("Widget must have a name");
}
if (!definition.type) {
throw new Error("Widget must have a type");
}
// Currently we only support output widgets
if (definition.type !== "output") {
throw new Error("Unrecognized widget type '" + definition.type + "'");
}
// TODO: Verify that .name is a valid CSS classname
// Support new-style instance-bound definitions. Old-style class-bound
// definitions have one widget "object" per widget per type/class of
// widget; the renderValue and resize methods on such widget objects
// take el and instance arguments, because the widget object can't
// store them. New-style instance-bound definitions have one widget
// object per widget instance; the definition that's passed in doesn't
// provide renderValue or resize methods at all, just the single method
// factory(el, width, height)
// which returns an object that has renderValue(x) and resize(w, h).
// This enables a far more natural programming style for the widget
// author, who can store per-instance state using either OO-style
// instance fields or functional-style closure variables (I guess this
// is in contrast to what can only be called C-style pseudo-OO which is
// what we required before).
if (definition.factory) {
definition = createLegacyDefinitionAdapter(definition);
}
if (!definition.renderValue) {
throw new Error("Widget must have a renderValue function");
}
// For static rendering (non-Shiny), use a simple widget registration
// scheme. We also use this scheme for Shiny apps/documents that also
// contain static widgets.
window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
// Merge defaults into the definition; don't mutate the original definition.
var staticBinding = extend({}, defaults, definition);
overrideMethod(staticBinding, "find", function(superfunc) {
return function(scope) {
var results = superfunc(scope);
// Filter out Shiny outputs, we only want the static kind
return filterByClass(results, "html-widget-output", false);
};
});
window.HTMLWidgets.widgets.push(staticBinding);
if (shinyMode) {
// Shiny is running. Register the definition with an output binding.
// The definition itself will not be the output binding, instead
// we will make an output binding object that delegates to the
// definition. This is because we foolishly used the same method
// name (renderValue) for htmlwidgets definition and Shiny bindings
// but they actually have quite different semantics (the Shiny
// bindings receive data that includes lots of metadata that it
// strips off before calling htmlwidgets renderValue). We can't
// just ignore the difference because in some widgets it's helpful
// to call this.renderValue() from inside of resize(), and if
// we're not delegating, then that call will go to the Shiny
// version instead of the htmlwidgets version.
// Merge defaults with definition, without mutating either.
var bindingDef = extend({}, defaults, definition);
// This object will be our actual Shiny binding.
var shinyBinding = new Shiny.OutputBinding();
// With a few exceptions, we'll want to simply use the bindingDef's
// version of methods if they are available, otherwise fall back to
// Shiny's defaults. NOTE: If Shiny's output bindings gain additional
// methods in the future, and we want them to be overrideable by
// HTMLWidget binding definitions, then we'll need to add them to this
// list.
delegateMethod(shinyBinding, bindingDef, "getId");
delegateMethod(shinyBinding, bindingDef, "onValueChange");
delegateMethod(shinyBinding, bindingDef, "onValueError");
delegateMethod(shinyBinding, bindingDef, "renderError");
delegateMethod(shinyBinding, bindingDef, "clearError");
delegateMethod(shinyBinding, bindingDef, "showProgress");
// The find, renderValue, and resize are handled differently, because we
// want to actually decorate the behavior of the bindingDef methods.
shinyBinding.find = function(scope) {
var results = bindingDef.find(scope);
// Only return elements that are Shiny outputs, not static ones
var dynamicResults = results.filter(".html-widget-output");
// It's possible that whatever caused Shiny to think there might be
// new dynamic outputs, also caused there to be new static outputs.
// Since there might be lots of different htmlwidgets bindings, we
// schedule execution for later--no need to staticRender multiple
// times.
if (results.length !== dynamicResults.length)
scheduleStaticRender();
return dynamicResults;
};
// Wrap renderValue to handle initialization, which unfortunately isn't
// supported natively by Shiny at the time of this writing.
shinyBinding.renderValue = function(el, data) {
Shiny.renderDependencies(data.deps);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var i = 0; data.evals && i < data.evals.length; i++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
}
if (!bindingDef.renderOnNullValue) {
if (data.x === null) {
el.style.visibility = "hidden";
return;
} else {
el.style.visibility = "inherit";
}
}
if (!elementData(el, "initialized")) {
initSizing(el);
elementData(el, "initialized", true);
if (bindingDef.initialize) {
var result = bindingDef.initialize(el, el.offsetWidth,
el.offsetHeight);
elementData(el, "init_result", result);
}
}
bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
};
// Only override resize if bindingDef implements it
if (bindingDef.resize) {
shinyBinding.resize = function(el, width, height) {
// Shiny can call resize before initialize/renderValue have been
// called, which doesn't make sense for widgets.
if (elementData(el, "initialized")) {
bindingDef.resize(el, width, height, elementData(el, "init_result"));
}
};
}
Shiny.outputBindings.register(shinyBinding, bindingDef.name);
}
};
var scheduleStaticRenderTimerId = null;
function scheduleStaticRender() {
if (!scheduleStaticRenderTimerId) {
scheduleStaticRenderTimerId = setTimeout(function() {
scheduleStaticRenderTimerId = null;
window.HTMLWidgets.staticRender();
}, 1);
}
}
// Render static widgets after the document finishes loading
// Statically render all elements that are of this widget's class
window.HTMLWidgets.staticRender = function() {
var bindings = window.HTMLWidgets.widgets || [];
forEach(bindings, function(binding) {
var matches = binding.find(document.documentElement);
forEach(matches, function(el) {
var sizeObj = initSizing(el, binding);
if (hasClass(el, "html-widget-static-bound"))
return;
el.className = el.className + " html-widget-static-bound";
var initResult;
if (binding.initialize) {
initResult = binding.initialize(el,
sizeObj ? sizeObj.getWidth() : el.offsetWidth,
sizeObj ? sizeObj.getHeight() : el.offsetHeight
);
elementData(el, "init_result", initResult);
}
if (binding.resize) {
var lastSize = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
var resizeHandler = function(e) {
var size = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
if (size.w === 0 && size.h === 0)
return;
if (size.w === lastSize.w && size.h === lastSize.h)
return;
lastSize = size;
binding.resize(el, size.w, size.h, initResult);
};
on(window, "resize", resizeHandler);
// This is needed for cases where we're running in a Shiny
// app, but the widget itself is not a Shiny output, but
// rather a simple static widget. One example of this is
// an rmarkdown document that has runtime:shiny and widget
// that isn't in a render function. Shiny only knows to
// call resize handlers for Shiny outputs, not for static
// widgets, so we do it ourselves.
if (window.jQuery) {
window.jQuery(document).on(
"shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
resizeHandler
);
window.jQuery(document).on(
"hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
resizeHandler
);
}
// This is needed for the specific case of ioslides, which
// flips slides between display:none and display:block.
// Ideally we would not have to have ioslide-specific code
// here, but rather have ioslides raise a generic event,
// but the rmarkdown package just went to CRAN so the
// window to getting that fixed may be long.
if (window.addEventListener) {
// It's OK to limit this to window.addEventListener
// browsers because ioslides itself only supports
// such browsers.
on(document, "slideenter", resizeHandler);
on(document, "slideleave", resizeHandler);
}
}
var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
if (scriptData) {
var data = JSON.parse(scriptData.textContent || scriptData.text);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var k = 0; data.evals && k < data.evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
}
binding.renderValue(el, data.x, initResult);
evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
}
});
});
invokePostRenderHandlers();
}
function has_jQuery3() {
if (!window.jQuery) {
return false;
}
var $version = window.jQuery.fn.jquery;
var $major_version = parseInt($version.split(".")[0]);
return $major_version >= 3;
}
/*
/ Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
/ on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
/ really means $(setTimeout(fn)).
/ https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
/
/ Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
/ one tick later than it did before, which means staticRender() is
/ called renderValue() earlier than (advanced) widget authors might be expecting.
/ https://github.com/rstudio/shiny/issues/2630
/
/ For a concrete example, leaflet has some methods (e.g., updateBounds)
/ which reference Shiny methods registered in initShiny (e.g., setInputValue).
/ Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
/ delay execution of those methods (until Shiny methods are ready)
/ https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
/
/ Ideally widget authors wouldn't need to use this setTimeout() hack that
/ leaflet uses to call Shiny methods on a staticRender(). In the long run,
/ the logic initShiny should be broken up so that method registration happens
/ right away, but binding happens later.
*/
function maybeStaticRenderLater() {
if (shinyMode && has_jQuery3()) {
window.jQuery(window.HTMLWidgets.staticRender);
} else {
window.HTMLWidgets.staticRender();
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
maybeStaticRenderLater();
}, false);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
maybeStaticRenderLater();
}
});
}
window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
// If no key, default to the first item
if (typeof(key) === "undefined")
key = 1;
var link = document.getElementById(depname + "-" + key + "-attachment");
if (!link) {
throw new Error("Attachment " + depname + "/" + key + " not found in document");
}
return link.getAttribute("href");
};
window.HTMLWidgets.dataframeToD3 = function(df) {
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
window.HTMLWidgets.transposeArray2D = function(array) {
if (array.length === 0) return array;
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
};
// Split value at splitChar, but allow splitChar to be escaped
// using escapeChar. Any other characters escaped by escapeChar
// will be included as usual (including escapeChar itself).
function splitWithEscape(value, splitChar, escapeChar) {
var results = [];
var escapeMode = false;
var currentResult = "";
for (var pos = 0; pos < value.length; pos++) {
if (!escapeMode) {
if (value[pos] === splitChar) {
results.push(currentResult);
currentResult = "";
} else if (value[pos] === escapeChar) {
escapeMode = true;
} else {
currentResult += value[pos];
}
} else {
currentResult += value[pos];
escapeMode = false;
}
}
if (currentResult !== "") {
results.push(currentResult);
}
return results;
}
// Function authored by Yihui/JJ Allaire
window.HTMLWidgets.evaluateStringMember = function(o, member) {
var parts = splitWithEscape(member, '.', '\\');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// part may be a character or 'numeric' member name
if (o !== null && typeof o === "object" && part in o) {
if (i == (l - 1)) { // if we are at the end of the line then evalulate
if (typeof o[part] === "string")
o[part] = tryEval(o[part]);
} else { // otherwise continue to next embedded object
o = o[part];
}
}
}
};
// Retrieve the HTMLWidget instance (i.e. the return value of an
// HTMLWidget binding's initialize() or factory() function)
// associated with an element, or null if none.
window.HTMLWidgets.getInstance = function(el) {
return elementData(el, "init_result");
};
// Finds the first element in the scope that matches the selector,
// and returns the HTMLWidget instance (i.e. the return value of
// an HTMLWidget binding's initialize() or factory() function)
// associated with that element, if any. If no element matches the
// selector, or the first matching element has no HTMLWidget
// instance associated with it, then null is returned.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.find = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var el = scope.querySelector(selector);
if (el === null) {
return null;
} else {
return window.HTMLWidgets.getInstance(el);
}
};
// Finds all elements in the scope that match the selector, and
// returns the HTMLWidget instances (i.e. the return values of
// an HTMLWidget binding's initialize() or factory() function)
// associated with the elements, in an array. If elements that
// match the selector don't have an associated HTMLWidget
// instance, the returned array will contain nulls.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.findAll = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var nodes = scope.querySelectorAll(selector);
var results = [];
for (var i = 0; i < nodes.length; i++) {
results.push(window.HTMLWidgets.getInstance(nodes[i]));
}
return results;
};
var postRenderHandlers = [];
function invokePostRenderHandlers() {
while (postRenderHandlers.length) {
var handler = postRenderHandlers.shift();
if (handler) {
handler();
}
}
}
// Register the given callback function to be invoked after the
// next time static widgets are rendered.
window.HTMLWidgets.addPostRenderHandler = function(callback) {
postRenderHandlers.push(callback);
};
// Takes a new-style instance-bound definition, and returns an
// old-style class-bound definition. This saves us from having
// to rewrite all the logic in this file to accomodate both
// types of definitions.
function createLegacyDefinitionAdapter(defn) {
var result = {
name: defn.name,
type: defn.type,
initialize: function(el, width, height) {
return defn.factory(el, width, height);
},
renderValue: function(el, x, instance) {
return instance.renderValue(x);
},
resize: function(el, width, height, instance) {
return instance.resize(width, height);
}
};
if (defn.find)
result.find = defn.find;
if (defn.renderError)
result.renderError = defn.renderError;
if (defn.clearError)
result.clearError = defn.clearError;
return result;
}
})();

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);
}
});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,903 +0,0 @@
(function() {
// If window.HTMLWidgets is already defined, then use it; otherwise create a
// new object. This allows preceding code to set options that affect the
// initialization process (though none currently exist).
window.HTMLWidgets = window.HTMLWidgets || {};
// See if we're running in a viewer pane. If not, we're in a web browser.
var viewerMode = window.HTMLWidgets.viewerMode =
/\bviewer_pane=1\b/.test(window.location);
// See if we're running in Shiny mode. If not, it's a static document.
// Note that static widgets can appear in both Shiny and static modes, but
// obviously, Shiny widgets can only appear in Shiny apps/documents.
var shinyMode = window.HTMLWidgets.shinyMode =
typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
// We can't count on jQuery being available, so we implement our own
// version if necessary.
function querySelectorAll(scope, selector) {
if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
return scope.find(selector);
}
if (scope.querySelectorAll) {
return scope.querySelectorAll(selector);
}
}
function asArray(value) {
if (value === null)
return [];
if ($.isArray(value))
return value;
return [value];
}
// Implement jQuery's extend
function extend(target /*, ... */) {
if (arguments.length == 1) {
return target;
}
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
// IE8 doesn't support Array.forEach.
function forEach(values, callback, thisArg) {
if (values.forEach) {
values.forEach(callback, thisArg);
} else {
for (var i = 0; i < values.length; i++) {
callback.call(thisArg, values[i], i, values);
}
}
}
// Replaces the specified method with the return value of funcSource.
//
// Note that funcSource should not BE the new method, it should be a function
// that RETURNS the new method. funcSource receives a single argument that is
// the overridden method, it can be called from the new method. The overridden
// method can be called like a regular function, it has the target permanently
// bound to it so "this" will work correctly.
function overrideMethod(target, methodName, funcSource) {
var superFunc = target[methodName] || function() {};
var superFuncBound = function() {
return superFunc.apply(target, arguments);
};
target[methodName] = funcSource(superFuncBound);
}
// Add a method to delegator that, when invoked, calls
// delegatee.methodName. If there is no such method on
// the delegatee, but there was one on delegator before
// delegateMethod was called, then the original version
// is invoked instead.
// For example:
//
// var a = {
// method1: function() { console.log('a1'); }
// method2: function() { console.log('a2'); }
// };
// var b = {
// method1: function() { console.log('b1'); }
// };
// delegateMethod(a, b, "method1");
// delegateMethod(a, b, "method2");
// a.method1();
// a.method2();
//
// The output would be "b1", "a2".
function delegateMethod(delegator, delegatee, methodName) {
var inherited = delegator[methodName];
delegator[methodName] = function() {
var target = delegatee;
var method = delegatee[methodName];
// The method doesn't exist on the delegatee. Instead,
// call the method on the delegator, if it exists.
if (!method) {
target = delegator;
method = inherited;
}
if (method) {
return method.apply(target, arguments);
}
};
}
// Implement a vague facsimilie of jQuery's data method
function elementData(el, name, value) {
if (arguments.length == 2) {
return el["htmlwidget_data_" + name];
} else if (arguments.length == 3) {
el["htmlwidget_data_" + name] = value;
return el;
} else {
throw new Error("Wrong number of arguments for elementData: " +
arguments.length);
}
}
// http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function hasClass(el, className) {
var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
return re.test(el.className);
}
// elements - array (or array-like object) of HTML elements
// className - class name to test for
// include - if true, only return elements with given className;
// if false, only return elements *without* given className
function filterByClass(elements, className, include) {
var results = [];
for (var i = 0; i < elements.length; i++) {
if (hasClass(elements[i], className) == include)
results.push(elements[i]);
}
return results;
}
function on(obj, eventName, func) {
if (obj.addEventListener) {
obj.addEventListener(eventName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(eventName, func);
}
}
function off(obj, eventName, func) {
if (obj.removeEventListener)
obj.removeEventListener(eventName, func, false);
else if (obj.detachEvent) {
obj.detachEvent(eventName, func);
}
}
// Translate array of values to top/right/bottom/left, as usual with
// the "padding" CSS property
// https://developer.mozilla.org/en-US/docs/Web/CSS/padding
function unpackPadding(value) {
if (typeof(value) === "number")
value = [value];
if (value.length === 1) {
return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
}
if (value.length === 2) {
return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
}
if (value.length === 3) {
return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
}
if (value.length === 4) {
return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
}
}
// Convert an unpacked padding object to a CSS value
function paddingToCss(paddingObj) {
return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
}
// Makes a number suitable for CSS
function px(x) {
if (typeof(x) === "number")
return x + "px";
else
return x;
}
// Retrieves runtime widget sizing information for an element.
// The return value is either null, or an object with fill, padding,
// defaultWidth, defaultHeight fields.
function sizingPolicy(el) {
var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
if (!sizingEl)
return null;
var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
if (viewerMode) {
return sp.viewer;
} else {
return sp.browser;
}
}
// @param tasks Array of strings (or falsy value, in which case no-op).
// Each element must be a valid JavaScript expression that yields a
// function. Or, can be an array of objects with "code" and "data"
// properties; in this case, the "code" property should be a string
// of JS that's an expr that yields a function, and "data" should be
// an object that will be added as an additional argument when that
// function is called.
// @param target The object that will be "this" for each function
// execution.
// @param args Array of arguments to be passed to the functions. (The
// same arguments will be passed to all functions.)
function evalAndRun(tasks, target, args) {
if (tasks) {
forEach(tasks, function(task) {
var theseArgs = args;
if (typeof(task) === "object") {
theseArgs = theseArgs.concat([task.data]);
task = task.code;
}
var taskFunc = tryEval(task);
if (typeof(taskFunc) !== "function") {
throw new Error("Task must be a function! Source:\n" + task);
}
taskFunc.apply(target, theseArgs);
});
}
}
// Attempt eval() both with and without enclosing in parentheses.
// Note that enclosing coerces a function declaration into
// an expression that eval() can parse
// (otherwise, a SyntaxError is thrown)
function tryEval(code) {
var result = null;
try {
result = eval(code);
} catch(error) {
if (!error instanceof SyntaxError) {
throw error;
}
try {
result = eval("(" + code + ")");
} catch(e) {
if (e instanceof SyntaxError) {
throw error;
} else {
throw e;
}
}
}
return result;
}
function initSizing(el) {
var sizing = sizingPolicy(el);
if (!sizing)
return;
var cel = document.getElementById("htmlwidget_container");
if (!cel)
return;
if (typeof(sizing.padding) !== "undefined") {
document.body.style.margin = "0";
document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
}
if (sizing.fill) {
document.body.style.overflow = "hidden";
document.body.style.width = "100%";
document.body.style.height = "100%";
document.documentElement.style.width = "100%";
document.documentElement.style.height = "100%";
if (cel) {
cel.style.position = "absolute";
var pad = unpackPadding(sizing.padding);
cel.style.top = pad.top + "px";
cel.style.right = pad.right + "px";
cel.style.bottom = pad.bottom + "px";
cel.style.left = pad.left + "px";
el.style.width = "100%";
el.style.height = "100%";
}
return {
getWidth: function() { return cel.offsetWidth; },
getHeight: function() { return cel.offsetHeight; }
};
} else {
el.style.width = px(sizing.width);
el.style.height = px(sizing.height);
return {
getWidth: function() { return el.offsetWidth; },
getHeight: function() { return el.offsetHeight; }
};
}
}
// Default implementations for methods
var defaults = {
find: function(scope) {
return querySelectorAll(scope, "." + this.name);
},
renderError: function(el, err) {
var $el = $(el);
this.clearError(el);
// Add all these error classes, as Shiny does
var errClass = "shiny-output-error";
if (err.type !== null) {
// use the classes of the error condition as CSS class names
errClass = errClass + " " + $.map(asArray(err.type), function(type) {
return errClass + "-" + type;
}).join(" ");
}
errClass = errClass + " htmlwidgets-error";
// Is el inline or block? If inline or inline-block, just display:none it
// and add an inline error.
var display = $el.css("display");
$el.data("restore-display-mode", display);
if (display === "inline" || display === "inline-block") {
$el.hide();
if (err.message !== "") {
var errorSpan = $("<span>").addClass(errClass);
errorSpan.text(err.message);
$el.after(errorSpan);
}
} else if (display === "block") {
// If block, add an error just after the el, set visibility:none on the
// el, and position the error to be on top of the el.
// Mark it with a unique ID and CSS class so we can remove it later.
$el.css("visibility", "hidden");
if (err.message !== "") {
var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
// setting width can push out the page size, forcing otherwise
// unnecessary scrollbars to appear and making it impossible for
// the element to shrink; so use max-width instead
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
errorDiv.text(err.message);
$el.after(errorDiv);
// Really dumb way to keep the size/position of the error in sync with
// the parent element as the window is resized or whatever.
var intId = setInterval(function() {
if (!errorDiv[0].parentElement) {
clearInterval(intId);
return;
}
errorDiv
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
}, 500);
}
}
},
clearError: function(el) {
var $el = $(el);
var display = $el.data("restore-display-mode");
$el.data("restore-display-mode", null);
if (display === "inline" || display === "inline-block") {
if (display)
$el.css("display", display);
$(el.nextSibling).filter(".htmlwidgets-error").remove();
} else if (display === "block"){
$el.css("visibility", "inherit");
$(el.nextSibling).filter(".htmlwidgets-error").remove();
}
},
sizing: {}
};
// Called by widget bindings to register a new type of widget. The definition
// object can contain the following properties:
// - name (required) - A string indicating the binding name, which will be
// used by default as the CSS classname to look for.
// - initialize (optional) - A function(el) that will be called once per
// widget element; if a value is returned, it will be passed as the third
// value to renderValue.
// - renderValue (required) - A function(el, data, initValue) that will be
// called with data. Static contexts will cause this to be called once per
// element; Shiny apps will cause this to be called multiple times per
// element, as the data changes.
window.HTMLWidgets.widget = function(definition) {
if (!definition.name) {
throw new Error("Widget must have a name");
}
if (!definition.type) {
throw new Error("Widget must have a type");
}
// Currently we only support output widgets
if (definition.type !== "output") {
throw new Error("Unrecognized widget type '" + definition.type + "'");
}
// TODO: Verify that .name is a valid CSS classname
// Support new-style instance-bound definitions. Old-style class-bound
// definitions have one widget "object" per widget per type/class of
// widget; the renderValue and resize methods on such widget objects
// take el and instance arguments, because the widget object can't
// store them. New-style instance-bound definitions have one widget
// object per widget instance; the definition that's passed in doesn't
// provide renderValue or resize methods at all, just the single method
// factory(el, width, height)
// which returns an object that has renderValue(x) and resize(w, h).
// This enables a far more natural programming style for the widget
// author, who can store per-instance state using either OO-style
// instance fields or functional-style closure variables (I guess this
// is in contrast to what can only be called C-style pseudo-OO which is
// what we required before).
if (definition.factory) {
definition = createLegacyDefinitionAdapter(definition);
}
if (!definition.renderValue) {
throw new Error("Widget must have a renderValue function");
}
// For static rendering (non-Shiny), use a simple widget registration
// scheme. We also use this scheme for Shiny apps/documents that also
// contain static widgets.
window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
// Merge defaults into the definition; don't mutate the original definition.
var staticBinding = extend({}, defaults, definition);
overrideMethod(staticBinding, "find", function(superfunc) {
return function(scope) {
var results = superfunc(scope);
// Filter out Shiny outputs, we only want the static kind
return filterByClass(results, "html-widget-output", false);
};
});
window.HTMLWidgets.widgets.push(staticBinding);
if (shinyMode) {
// Shiny is running. Register the definition with an output binding.
// The definition itself will not be the output binding, instead
// we will make an output binding object that delegates to the
// definition. This is because we foolishly used the same method
// name (renderValue) for htmlwidgets definition and Shiny bindings
// but they actually have quite different semantics (the Shiny
// bindings receive data that includes lots of metadata that it
// strips off before calling htmlwidgets renderValue). We can't
// just ignore the difference because in some widgets it's helpful
// to call this.renderValue() from inside of resize(), and if
// we're not delegating, then that call will go to the Shiny
// version instead of the htmlwidgets version.
// Merge defaults with definition, without mutating either.
var bindingDef = extend({}, defaults, definition);
// This object will be our actual Shiny binding.
var shinyBinding = new Shiny.OutputBinding();
// With a few exceptions, we'll want to simply use the bindingDef's
// version of methods if they are available, otherwise fall back to
// Shiny's defaults. NOTE: If Shiny's output bindings gain additional
// methods in the future, and we want them to be overrideable by
// HTMLWidget binding definitions, then we'll need to add them to this
// list.
delegateMethod(shinyBinding, bindingDef, "getId");
delegateMethod(shinyBinding, bindingDef, "onValueChange");
delegateMethod(shinyBinding, bindingDef, "onValueError");
delegateMethod(shinyBinding, bindingDef, "renderError");
delegateMethod(shinyBinding, bindingDef, "clearError");
delegateMethod(shinyBinding, bindingDef, "showProgress");
// The find, renderValue, and resize are handled differently, because we
// want to actually decorate the behavior of the bindingDef methods.
shinyBinding.find = function(scope) {
var results = bindingDef.find(scope);
// Only return elements that are Shiny outputs, not static ones
var dynamicResults = results.filter(".html-widget-output");
// It's possible that whatever caused Shiny to think there might be
// new dynamic outputs, also caused there to be new static outputs.
// Since there might be lots of different htmlwidgets bindings, we
// schedule execution for later--no need to staticRender multiple
// times.
if (results.length !== dynamicResults.length)
scheduleStaticRender();
return dynamicResults;
};
// Wrap renderValue to handle initialization, which unfortunately isn't
// supported natively by Shiny at the time of this writing.
shinyBinding.renderValue = function(el, data) {
Shiny.renderDependencies(data.deps);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var i = 0; data.evals && i < data.evals.length; i++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
}
if (!bindingDef.renderOnNullValue) {
if (data.x === null) {
el.style.visibility = "hidden";
return;
} else {
el.style.visibility = "inherit";
}
}
if (!elementData(el, "initialized")) {
initSizing(el);
elementData(el, "initialized", true);
if (bindingDef.initialize) {
var result = bindingDef.initialize(el, el.offsetWidth,
el.offsetHeight);
elementData(el, "init_result", result);
}
}
bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
};
// Only override resize if bindingDef implements it
if (bindingDef.resize) {
shinyBinding.resize = function(el, width, height) {
// Shiny can call resize before initialize/renderValue have been
// called, which doesn't make sense for widgets.
if (elementData(el, "initialized")) {
bindingDef.resize(el, width, height, elementData(el, "init_result"));
}
};
}
Shiny.outputBindings.register(shinyBinding, bindingDef.name);
}
};
var scheduleStaticRenderTimerId = null;
function scheduleStaticRender() {
if (!scheduleStaticRenderTimerId) {
scheduleStaticRenderTimerId = setTimeout(function() {
scheduleStaticRenderTimerId = null;
window.HTMLWidgets.staticRender();
}, 1);
}
}
// Render static widgets after the document finishes loading
// Statically render all elements that are of this widget's class
window.HTMLWidgets.staticRender = function() {
var bindings = window.HTMLWidgets.widgets || [];
forEach(bindings, function(binding) {
var matches = binding.find(document.documentElement);
forEach(matches, function(el) {
var sizeObj = initSizing(el, binding);
if (hasClass(el, "html-widget-static-bound"))
return;
el.className = el.className + " html-widget-static-bound";
var initResult;
if (binding.initialize) {
initResult = binding.initialize(el,
sizeObj ? sizeObj.getWidth() : el.offsetWidth,
sizeObj ? sizeObj.getHeight() : el.offsetHeight
);
elementData(el, "init_result", initResult);
}
if (binding.resize) {
var lastSize = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
var resizeHandler = function(e) {
var size = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
if (size.w === 0 && size.h === 0)
return;
if (size.w === lastSize.w && size.h === lastSize.h)
return;
lastSize = size;
binding.resize(el, size.w, size.h, initResult);
};
on(window, "resize", resizeHandler);
// This is needed for cases where we're running in a Shiny
// app, but the widget itself is not a Shiny output, but
// rather a simple static widget. One example of this is
// an rmarkdown document that has runtime:shiny and widget
// that isn't in a render function. Shiny only knows to
// call resize handlers for Shiny outputs, not for static
// widgets, so we do it ourselves.
if (window.jQuery) {
window.jQuery(document).on(
"shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
resizeHandler
);
window.jQuery(document).on(
"hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
resizeHandler
);
}
// This is needed for the specific case of ioslides, which
// flips slides between display:none and display:block.
// Ideally we would not have to have ioslide-specific code
// here, but rather have ioslides raise a generic event,
// but the rmarkdown package just went to CRAN so the
// window to getting that fixed may be long.
if (window.addEventListener) {
// It's OK to limit this to window.addEventListener
// browsers because ioslides itself only supports
// such browsers.
on(document, "slideenter", resizeHandler);
on(document, "slideleave", resizeHandler);
}
}
var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
if (scriptData) {
var data = JSON.parse(scriptData.textContent || scriptData.text);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var k = 0; data.evals && k < data.evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
}
binding.renderValue(el, data.x, initResult);
evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
}
});
});
invokePostRenderHandlers();
}
function has_jQuery3() {
if (!window.jQuery) {
return false;
}
var $version = window.jQuery.fn.jquery;
var $major_version = parseInt($version.split(".")[0]);
return $major_version >= 3;
}
/*
/ Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
/ on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
/ really means $(setTimeout(fn)).
/ https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
/
/ Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
/ one tick later than it did before, which means staticRender() is
/ called renderValue() earlier than (advanced) widget authors might be expecting.
/ https://github.com/rstudio/shiny/issues/2630
/
/ For a concrete example, leaflet has some methods (e.g., updateBounds)
/ which reference Shiny methods registered in initShiny (e.g., setInputValue).
/ Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
/ delay execution of those methods (until Shiny methods are ready)
/ https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
/
/ Ideally widget authors wouldn't need to use this setTimeout() hack that
/ leaflet uses to call Shiny methods on a staticRender(). In the long run,
/ the logic initShiny should be broken up so that method registration happens
/ right away, but binding happens later.
*/
function maybeStaticRenderLater() {
if (shinyMode && has_jQuery3()) {
window.jQuery(window.HTMLWidgets.staticRender);
} else {
window.HTMLWidgets.staticRender();
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
maybeStaticRenderLater();
}, false);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
maybeStaticRenderLater();
}
});
}
window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
// If no key, default to the first item
if (typeof(key) === "undefined")
key = 1;
var link = document.getElementById(depname + "-" + key + "-attachment");
if (!link) {
throw new Error("Attachment " + depname + "/" + key + " not found in document");
}
return link.getAttribute("href");
};
window.HTMLWidgets.dataframeToD3 = function(df) {
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
window.HTMLWidgets.transposeArray2D = function(array) {
if (array.length === 0) return array;
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
};
// Split value at splitChar, but allow splitChar to be escaped
// using escapeChar. Any other characters escaped by escapeChar
// will be included as usual (including escapeChar itself).
function splitWithEscape(value, splitChar, escapeChar) {
var results = [];
var escapeMode = false;
var currentResult = "";
for (var pos = 0; pos < value.length; pos++) {
if (!escapeMode) {
if (value[pos] === splitChar) {
results.push(currentResult);
currentResult = "";
} else if (value[pos] === escapeChar) {
escapeMode = true;
} else {
currentResult += value[pos];
}
} else {
currentResult += value[pos];
escapeMode = false;
}
}
if (currentResult !== "") {
results.push(currentResult);
}
return results;
}
// Function authored by Yihui/JJ Allaire
window.HTMLWidgets.evaluateStringMember = function(o, member) {
var parts = splitWithEscape(member, '.', '\\');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// part may be a character or 'numeric' member name
if (o !== null && typeof o === "object" && part in o) {
if (i == (l - 1)) { // if we are at the end of the line then evalulate
if (typeof o[part] === "string")
o[part] = tryEval(o[part]);
} else { // otherwise continue to next embedded object
o = o[part];
}
}
}
};
// Retrieve the HTMLWidget instance (i.e. the return value of an
// HTMLWidget binding's initialize() or factory() function)
// associated with an element, or null if none.
window.HTMLWidgets.getInstance = function(el) {
return elementData(el, "init_result");
};
// Finds the first element in the scope that matches the selector,
// and returns the HTMLWidget instance (i.e. the return value of
// an HTMLWidget binding's initialize() or factory() function)
// associated with that element, if any. If no element matches the
// selector, or the first matching element has no HTMLWidget
// instance associated with it, then null is returned.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.find = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var el = scope.querySelector(selector);
if (el === null) {
return null;
} else {
return window.HTMLWidgets.getInstance(el);
}
};
// Finds all elements in the scope that match the selector, and
// returns the HTMLWidget instances (i.e. the return values of
// an HTMLWidget binding's initialize() or factory() function)
// associated with the elements, in an array. If elements that
// match the selector don't have an associated HTMLWidget
// instance, the returned array will contain nulls.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.findAll = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var nodes = scope.querySelectorAll(selector);
var results = [];
for (var i = 0; i < nodes.length; i++) {
results.push(window.HTMLWidgets.getInstance(nodes[i]));
}
return results;
};
var postRenderHandlers = [];
function invokePostRenderHandlers() {
while (postRenderHandlers.length) {
var handler = postRenderHandlers.shift();
if (handler) {
handler();
}
}
}
// Register the given callback function to be invoked after the
// next time static widgets are rendered.
window.HTMLWidgets.addPostRenderHandler = function(callback) {
postRenderHandlers.push(callback);
};
// Takes a new-style instance-bound definition, and returns an
// old-style class-bound definition. This saves us from having
// to rewrite all the logic in this file to accomodate both
// types of definitions.
function createLegacyDefinitionAdapter(defn) {
var result = {
name: defn.name,
type: defn.type,
initialize: function(el, width, height) {
return defn.factory(el, width, height);
},
renderValue: function(el, x, instance) {
return instance.renderValue(x);
},
resize: function(el, width, height, instance) {
return instance.resize(width, height);
}
};
if (defn.find)
result.find = defn.find;
if (defn.renderError)
result.renderError = defn.renderError;
if (defn.clearError)
result.clearError = defn.clearError;
return result;
}
})();

View File

@ -1,238 +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>Articles • apexcharter</title>
<!-- jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<link href="../css/theme.css" rel="stylesheet">
<!-- Font -->
<link href="../css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- Particles -->
<script src="../js/particles.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></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="Articles" />
<!-- 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-article-index">
<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.3.990</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.3.990</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/labs.html">Labs: title, subtitle &amp; axis</a>
</li>
<li>
<a href="../articles/lines.html">Options &amp; styles for lines</a>
</li>
<li>
<a href="../articles/shiny-integration.html">Shiny integration</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="col-md-9 contents">
<div class="page-header">
<h1>Articles</h1>
</div>
<div class="section ">
<h3>All vignettes</h3>
<p class="section-desc"></p>
<ul>
<li><a href="apexcharter.html">Starting with ApexCharts</a></li>
<li><a href="articles/advanced-configuration.html">Advanced configuration examples</a></li>
<li><a href="labs.html">Labs: title, subtitle &amp; axis</a></li>
<li><a href="lines.html">Options &amp; styles for lines</a></li>
<li><a href="shiny-integration.html">Shiny integration</a></li>
<li><a href="sync-charts.html">Syncing charts</a></li>
</ul>
</div>
</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.4.1.</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,263 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<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>Labs: title, subtitle &amp; axis • apexcharter</title>
<!-- jquery --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script><!-- Bootstrap --><link href="../css/theme.css" rel="stylesheet">
<!-- Font --><link href="../css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- Particles --><script src="../js/particles.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></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="Labs: title, subtitle &amp; axis">
<meta property="og:description" content="">
<meta name="twitter:card" content="summary">
<!-- 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-article">
<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.3.990</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.3.990</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/labs.html">Labs: title, subtitle &amp; axis</a>
</li>
<li>
<a href="../articles/lines.html">Options &amp; styles for lines</a>
</li>
<li>
<a href="../articles/shiny-integration.html">Shiny integration</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><script src="labs_files/htmlwidgets-1.5.1/htmlwidgets.js"></script><script src="labs_files/apexcharts-3.17.1/apexcharts.min.js"></script><script src="labs_files/d3-format-1.4.2/d3-format.min.js"></script><script src="labs_files/apexcharter-binding-0.1.3.990/apexcharter.js"></script><div class="row">
<div class="col-md-9 contents">
<div class="page-header toc-ignore">
<h1>Labs: title, subtitle &amp; axis</h1>
<small class="dont-index">Source: <a href="https://github.com/dreamRs/apexcharter/blob/master/vignettes/labs.Rmd"><code>vignettes/labs.Rmd</code></a></small>
<div class="hidden name"><code>labs.Rmd</code></div>
</div>
<p>Packages and data used below:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb1-1" title="1"><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span>(apexcharter)</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span>(dplyr)</a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4"><span class="kw"><a href="https://rdrr.io/r/utils/data.html">data</a></span>(<span class="st">"diamonds"</span>, <span class="dt">package =</span> <span class="st">"ggplot2"</span>)</a>
<a class="sourceLine" id="cb1-5" title="5">n_cut &lt;-<span class="st"> </span>dplyr<span class="op">::</span><span class="kw"><a href="https://dplyr.tidyverse.org/reference/tally.html">count</a></span>(diamonds, cut)</a></code></pre></div>
<div id="chart-title" class="section level2">
<h2 class="hasAnchor">
<a href="#chart-title" class="anchor"></a>Chart title</h2>
<div class="sourceCode" id="cb2"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb2-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> n_cut, <span class="dt">type =</span> <span class="st">"column"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> cut, <span class="dt">y =</span> n)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_title.html">ax_title</a></span>(<span class="dt">text =</span> <span class="st">"Cut distribution"</span>)</a></code></pre></div>
<div id="htmlwidget-8e78491cd40784e13eda" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-8e78491cd40784e13eda">{"x":{"ax_opts":{"chart":{"type":"bar"},"series":[{"name":"n","data":[{"x":"Fair","y":1610},{"x":"Good","y":4906},{"x":"Very Good","y":12082},{"x":"Premium","y":13791},{"x":"Ideal","y":21551}]}],"dataLabels":{"enabled":false},"plotOptions":{"bar":{"horizontal":false}},"title":{"text":"Cut distribution"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":[],"jsHooks":[]}</script><p>You can set some options, for example:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb3-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> n_cut, <span class="dt">type =</span> <span class="st">"column"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> cut, <span class="dt">y =</span> n)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_title.html">ax_title</a></span>(</a>
<a class="sourceLine" id="cb3-3" title="3"> <span class="dt">text =</span> <span class="st">"Cut distribution"</span>, </a>
<a class="sourceLine" id="cb3-4" title="4"> <span class="dt">align =</span> <span class="st">"center"</span>,</a>
<a class="sourceLine" id="cb3-5" title="5"> <span class="dt">style =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">fontSize =</span> <span class="st">"22px"</span>)</a>
<a class="sourceLine" id="cb3-6" title="6"> )</a></code></pre></div>
<div id="htmlwidget-e070758776ee7dfb0950" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-e070758776ee7dfb0950">{"x":{"ax_opts":{"chart":{"type":"bar"},"series":[{"name":"n","data":[{"x":"Fair","y":1610},{"x":"Good","y":4906},{"x":"Very Good","y":12082},{"x":"Premium","y":13791},{"x":"Ideal","y":21551}]}],"dataLabels":{"enabled":false},"plotOptions":{"bar":{"horizontal":false}},"title":{"text":"Cut distribution","align":"center","style":{"fontSize":"22px"}}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":[],"jsHooks":[]}</script><p>Full list of parameters is available here : <a href="https://apexcharts.com/docs/options/title/" class="uri">https://apexcharts.com/docs/options/title/</a></p>
</div>
<div id="chart-subtitle" class="section level2">
<h2 class="hasAnchor">
<a href="#chart-subtitle" class="anchor"></a>Chart subtitle</h2>
<div class="sourceCode" id="cb4"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb4-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> n_cut, <span class="dt">type =</span> <span class="st">"column"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> cut, <span class="dt">y =</span> n)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_title.html">ax_title</a></span>(<span class="dt">text =</span> <span class="st">"Cut distribution"</span>) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb4-3" title="3"><span class="st"> </span><span class="kw"><a href="../reference/ax_subtitle.html">ax_subtitle</a></span>(<span class="dt">text =</span> <span class="st">"Data from ggplot2"</span>)</a></code></pre></div>
<div id="htmlwidget-9c636cf1c5e3ab9788ce" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-9c636cf1c5e3ab9788ce">{"x":{"ax_opts":{"chart":{"type":"bar"},"series":[{"name":"n","data":[{"x":"Fair","y":1610},{"x":"Good","y":4906},{"x":"Very Good","y":12082},{"x":"Premium","y":13791},{"x":"Ideal","y":21551}]}],"dataLabels":{"enabled":false},"plotOptions":{"bar":{"horizontal":false}},"title":{"text":"Cut distribution"},"subtitle":{"text":"Data from ggplot2"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":[],"jsHooks":[]}</script><p>With same options than for title:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb5-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> n_cut, <span class="dt">type =</span> <span class="st">"column"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> cut, <span class="dt">y =</span> n)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_title.html">ax_title</a></span>(</a>
<a class="sourceLine" id="cb5-3" title="3"> <span class="dt">text =</span> <span class="st">"Cut distribution"</span>, </a>
<a class="sourceLine" id="cb5-4" title="4"> <span class="dt">align =</span> <span class="st">"center"</span>,</a>
<a class="sourceLine" id="cb5-5" title="5"> <span class="dt">style =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">fontSize =</span> <span class="st">"22px"</span>)</a>
<a class="sourceLine" id="cb5-6" title="6"> ) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb5-7" title="7"><span class="st"> </span><span class="kw"><a href="../reference/ax_subtitle.html">ax_subtitle</a></span>(</a>
<a class="sourceLine" id="cb5-8" title="8"> <span class="dt">text =</span> <span class="st">"Data from ggplot2"</span>, </a>
<a class="sourceLine" id="cb5-9" title="9"> <span class="dt">align =</span> <span class="st">"center"</span>,</a>
<a class="sourceLine" id="cb5-10" title="10"> <span class="dt">style =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">fontSize =</span> <span class="st">"16px"</span>, <span class="dt">color =</span> <span class="st">"#BDBDBD"</span>)</a>
<a class="sourceLine" id="cb5-11" title="11"> )</a></code></pre></div>
<div id="htmlwidget-71e26737e7e204286149" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-71e26737e7e204286149">{"x":{"ax_opts":{"chart":{"type":"bar"},"series":[{"name":"n","data":[{"x":"Fair","y":1610},{"x":"Good","y":4906},{"x":"Very Good","y":12082},{"x":"Premium","y":13791},{"x":"Ideal","y":21551}]}],"dataLabels":{"enabled":false},"plotOptions":{"bar":{"horizontal":false}},"title":{"text":"Cut distribution","align":"center","style":{"fontSize":"22px"}},"subtitle":{"text":"Data from ggplot2","align":"center","style":{"fontSize":"16px","color":"#BDBDBD"}}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":[],"jsHooks":[]}</script><p>Full list of parameters is available here : <a href="https://apexcharts.com/docs/options/subtitle/" class="uri">https://apexcharts.com/docs/options/subtitle/</a></p>
</div>
<div id="axis-title" class="section level2">
<h2 class="hasAnchor">
<a href="#axis-title" class="anchor"></a>Axis title</h2>
<div class="sourceCode" id="cb6"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb6-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> n_cut, <span class="dt">type =</span> <span class="st">"column"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> cut, <span class="dt">y =</span> n)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb6-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_yaxis.html">ax_yaxis</a></span>(<span class="dt">title =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">text =</span> <span class="st">"Count"</span>)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb6-3" title="3"><span class="st"> </span><span class="kw"><a href="../reference/ax_xaxis.html">ax_xaxis</a></span>(<span class="dt">title =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">text =</span> <span class="st">"Cut"</span>))</a></code></pre></div>
<div id="htmlwidget-daf91496798eacfb2351" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-daf91496798eacfb2351">{"x":{"ax_opts":{"chart":{"type":"bar"},"series":[{"name":"n","data":[{"x":"Fair","y":1610},{"x":"Good","y":4906},{"x":"Very Good","y":12082},{"x":"Premium","y":13791},{"x":"Ideal","y":21551}]}],"dataLabels":{"enabled":false},"plotOptions":{"bar":{"horizontal":false}},"yaxis":{"title":{"text":"Count"}},"xaxis":{"title":{"text":"Cut"}}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":[],"jsHooks":[]}</script><p>With some options:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb7-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> n_cut, <span class="dt">type =</span> <span class="st">"column"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> cut, <span class="dt">y =</span> n)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb7-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_yaxis.html">ax_yaxis</a></span>(<span class="dt">title =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(</a>
<a class="sourceLine" id="cb7-3" title="3"> <span class="dt">text =</span> <span class="st">"Count"</span>,</a>
<a class="sourceLine" id="cb7-4" title="4"> <span class="dt">style =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">fontSize =</span> <span class="st">"14px"</span>, <span class="dt">color =</span> <span class="st">"#BDBDBD"</span>)</a>
<a class="sourceLine" id="cb7-5" title="5"> )) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb7-6" title="6"><span class="st"> </span><span class="kw"><a href="../reference/ax_xaxis.html">ax_xaxis</a></span>(<span class="dt">title =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(</a>
<a class="sourceLine" id="cb7-7" title="7"> <span class="dt">text =</span> <span class="st">"Cut"</span>, </a>
<a class="sourceLine" id="cb7-8" title="8"> <span class="dt">style =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="dt">fontSize =</span> <span class="st">"14px"</span>, <span class="dt">color =</span> <span class="st">"#BDBDBD"</span>)</a>
<a class="sourceLine" id="cb7-9" title="9"> ))</a></code></pre></div>
<div id="htmlwidget-4939f88476fd086e16f8" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-4939f88476fd086e16f8">{"x":{"ax_opts":{"chart":{"type":"bar"},"series":[{"name":"n","data":[{"x":"Fair","y":1610},{"x":"Good","y":4906},{"x":"Very Good","y":12082},{"x":"Premium","y":13791},{"x":"Ideal","y":21551}]}],"dataLabels":{"enabled":false},"plotOptions":{"bar":{"horizontal":false}},"yaxis":{"title":{"text":"Count","style":{"fontSize":"14px","color":"#BDBDBD"}}},"xaxis":{"title":{"text":"Cut","style":{"fontSize":"14px","color":"#BDBDBD"}}}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":[],"jsHooks":[]}</script>
</div>
</div>
<div class="col-md-3 hidden-xs hidden-sm" id="sidebar">
<div id="tocnav">
<h2 class="hasAnchor">
<a href="#tocnav" class="anchor"></a>Contents</h2>
<ul class="nav nav-pills nav-stacked">
<li><a href="#chart-title">Chart title</a></li>
<li><a href="#chart-subtitle">Chart subtitle</a></li>
<li><a href="#axis-title">Axis title</a></li>
</ul>
</div>
</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.4.1.</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

File diff suppressed because one or more lines are too long

View File

@ -1,903 +0,0 @@
(function() {
// If window.HTMLWidgets is already defined, then use it; otherwise create a
// new object. This allows preceding code to set options that affect the
// initialization process (though none currently exist).
window.HTMLWidgets = window.HTMLWidgets || {};
// See if we're running in a viewer pane. If not, we're in a web browser.
var viewerMode = window.HTMLWidgets.viewerMode =
/\bviewer_pane=1\b/.test(window.location);
// See if we're running in Shiny mode. If not, it's a static document.
// Note that static widgets can appear in both Shiny and static modes, but
// obviously, Shiny widgets can only appear in Shiny apps/documents.
var shinyMode = window.HTMLWidgets.shinyMode =
typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
// We can't count on jQuery being available, so we implement our own
// version if necessary.
function querySelectorAll(scope, selector) {
if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
return scope.find(selector);
}
if (scope.querySelectorAll) {
return scope.querySelectorAll(selector);
}
}
function asArray(value) {
if (value === null)
return [];
if ($.isArray(value))
return value;
return [value];
}
// Implement jQuery's extend
function extend(target /*, ... */) {
if (arguments.length == 1) {
return target;
}
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
// IE8 doesn't support Array.forEach.
function forEach(values, callback, thisArg) {
if (values.forEach) {
values.forEach(callback, thisArg);
} else {
for (var i = 0; i < values.length; i++) {
callback.call(thisArg, values[i], i, values);
}
}
}
// Replaces the specified method with the return value of funcSource.
//
// Note that funcSource should not BE the new method, it should be a function
// that RETURNS the new method. funcSource receives a single argument that is
// the overridden method, it can be called from the new method. The overridden
// method can be called like a regular function, it has the target permanently
// bound to it so "this" will work correctly.
function overrideMethod(target, methodName, funcSource) {
var superFunc = target[methodName] || function() {};
var superFuncBound = function() {
return superFunc.apply(target, arguments);
};
target[methodName] = funcSource(superFuncBound);
}
// Add a method to delegator that, when invoked, calls
// delegatee.methodName. If there is no such method on
// the delegatee, but there was one on delegator before
// delegateMethod was called, then the original version
// is invoked instead.
// For example:
//
// var a = {
// method1: function() { console.log('a1'); }
// method2: function() { console.log('a2'); }
// };
// var b = {
// method1: function() { console.log('b1'); }
// };
// delegateMethod(a, b, "method1");
// delegateMethod(a, b, "method2");
// a.method1();
// a.method2();
//
// The output would be "b1", "a2".
function delegateMethod(delegator, delegatee, methodName) {
var inherited = delegator[methodName];
delegator[methodName] = function() {
var target = delegatee;
var method = delegatee[methodName];
// The method doesn't exist on the delegatee. Instead,
// call the method on the delegator, if it exists.
if (!method) {
target = delegator;
method = inherited;
}
if (method) {
return method.apply(target, arguments);
}
};
}
// Implement a vague facsimilie of jQuery's data method
function elementData(el, name, value) {
if (arguments.length == 2) {
return el["htmlwidget_data_" + name];
} else if (arguments.length == 3) {
el["htmlwidget_data_" + name] = value;
return el;
} else {
throw new Error("Wrong number of arguments for elementData: " +
arguments.length);
}
}
// http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function hasClass(el, className) {
var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
return re.test(el.className);
}
// elements - array (or array-like object) of HTML elements
// className - class name to test for
// include - if true, only return elements with given className;
// if false, only return elements *without* given className
function filterByClass(elements, className, include) {
var results = [];
for (var i = 0; i < elements.length; i++) {
if (hasClass(elements[i], className) == include)
results.push(elements[i]);
}
return results;
}
function on(obj, eventName, func) {
if (obj.addEventListener) {
obj.addEventListener(eventName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(eventName, func);
}
}
function off(obj, eventName, func) {
if (obj.removeEventListener)
obj.removeEventListener(eventName, func, false);
else if (obj.detachEvent) {
obj.detachEvent(eventName, func);
}
}
// Translate array of values to top/right/bottom/left, as usual with
// the "padding" CSS property
// https://developer.mozilla.org/en-US/docs/Web/CSS/padding
function unpackPadding(value) {
if (typeof(value) === "number")
value = [value];
if (value.length === 1) {
return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
}
if (value.length === 2) {
return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
}
if (value.length === 3) {
return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
}
if (value.length === 4) {
return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
}
}
// Convert an unpacked padding object to a CSS value
function paddingToCss(paddingObj) {
return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
}
// Makes a number suitable for CSS
function px(x) {
if (typeof(x) === "number")
return x + "px";
else
return x;
}
// Retrieves runtime widget sizing information for an element.
// The return value is either null, or an object with fill, padding,
// defaultWidth, defaultHeight fields.
function sizingPolicy(el) {
var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
if (!sizingEl)
return null;
var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
if (viewerMode) {
return sp.viewer;
} else {
return sp.browser;
}
}
// @param tasks Array of strings (or falsy value, in which case no-op).
// Each element must be a valid JavaScript expression that yields a
// function. Or, can be an array of objects with "code" and "data"
// properties; in this case, the "code" property should be a string
// of JS that's an expr that yields a function, and "data" should be
// an object that will be added as an additional argument when that
// function is called.
// @param target The object that will be "this" for each function
// execution.
// @param args Array of arguments to be passed to the functions. (The
// same arguments will be passed to all functions.)
function evalAndRun(tasks, target, args) {
if (tasks) {
forEach(tasks, function(task) {
var theseArgs = args;
if (typeof(task) === "object") {
theseArgs = theseArgs.concat([task.data]);
task = task.code;
}
var taskFunc = tryEval(task);
if (typeof(taskFunc) !== "function") {
throw new Error("Task must be a function! Source:\n" + task);
}
taskFunc.apply(target, theseArgs);
});
}
}
// Attempt eval() both with and without enclosing in parentheses.
// Note that enclosing coerces a function declaration into
// an expression that eval() can parse
// (otherwise, a SyntaxError is thrown)
function tryEval(code) {
var result = null;
try {
result = eval(code);
} catch(error) {
if (!error instanceof SyntaxError) {
throw error;
}
try {
result = eval("(" + code + ")");
} catch(e) {
if (e instanceof SyntaxError) {
throw error;
} else {
throw e;
}
}
}
return result;
}
function initSizing(el) {
var sizing = sizingPolicy(el);
if (!sizing)
return;
var cel = document.getElementById("htmlwidget_container");
if (!cel)
return;
if (typeof(sizing.padding) !== "undefined") {
document.body.style.margin = "0";
document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
}
if (sizing.fill) {
document.body.style.overflow = "hidden";
document.body.style.width = "100%";
document.body.style.height = "100%";
document.documentElement.style.width = "100%";
document.documentElement.style.height = "100%";
if (cel) {
cel.style.position = "absolute";
var pad = unpackPadding(sizing.padding);
cel.style.top = pad.top + "px";
cel.style.right = pad.right + "px";
cel.style.bottom = pad.bottom + "px";
cel.style.left = pad.left + "px";
el.style.width = "100%";
el.style.height = "100%";
}
return {
getWidth: function() { return cel.offsetWidth; },
getHeight: function() { return cel.offsetHeight; }
};
} else {
el.style.width = px(sizing.width);
el.style.height = px(sizing.height);
return {
getWidth: function() { return el.offsetWidth; },
getHeight: function() { return el.offsetHeight; }
};
}
}
// Default implementations for methods
var defaults = {
find: function(scope) {
return querySelectorAll(scope, "." + this.name);
},
renderError: function(el, err) {
var $el = $(el);
this.clearError(el);
// Add all these error classes, as Shiny does
var errClass = "shiny-output-error";
if (err.type !== null) {
// use the classes of the error condition as CSS class names
errClass = errClass + " " + $.map(asArray(err.type), function(type) {
return errClass + "-" + type;
}).join(" ");
}
errClass = errClass + " htmlwidgets-error";
// Is el inline or block? If inline or inline-block, just display:none it
// and add an inline error.
var display = $el.css("display");
$el.data("restore-display-mode", display);
if (display === "inline" || display === "inline-block") {
$el.hide();
if (err.message !== "") {
var errorSpan = $("<span>").addClass(errClass);
errorSpan.text(err.message);
$el.after(errorSpan);
}
} else if (display === "block") {
// If block, add an error just after the el, set visibility:none on the
// el, and position the error to be on top of the el.
// Mark it with a unique ID and CSS class so we can remove it later.
$el.css("visibility", "hidden");
if (err.message !== "") {
var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
// setting width can push out the page size, forcing otherwise
// unnecessary scrollbars to appear and making it impossible for
// the element to shrink; so use max-width instead
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
errorDiv.text(err.message);
$el.after(errorDiv);
// Really dumb way to keep the size/position of the error in sync with
// the parent element as the window is resized or whatever.
var intId = setInterval(function() {
if (!errorDiv[0].parentElement) {
clearInterval(intId);
return;
}
errorDiv
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
}, 500);
}
}
},
clearError: function(el) {
var $el = $(el);
var display = $el.data("restore-display-mode");
$el.data("restore-display-mode", null);
if (display === "inline" || display === "inline-block") {
if (display)
$el.css("display", display);
$(el.nextSibling).filter(".htmlwidgets-error").remove();
} else if (display === "block"){
$el.css("visibility", "inherit");
$(el.nextSibling).filter(".htmlwidgets-error").remove();
}
},
sizing: {}
};
// Called by widget bindings to register a new type of widget. The definition
// object can contain the following properties:
// - name (required) - A string indicating the binding name, which will be
// used by default as the CSS classname to look for.
// - initialize (optional) - A function(el) that will be called once per
// widget element; if a value is returned, it will be passed as the third
// value to renderValue.
// - renderValue (required) - A function(el, data, initValue) that will be
// called with data. Static contexts will cause this to be called once per
// element; Shiny apps will cause this to be called multiple times per
// element, as the data changes.
window.HTMLWidgets.widget = function(definition) {
if (!definition.name) {
throw new Error("Widget must have a name");
}
if (!definition.type) {
throw new Error("Widget must have a type");
}
// Currently we only support output widgets
if (definition.type !== "output") {
throw new Error("Unrecognized widget type '" + definition.type + "'");
}
// TODO: Verify that .name is a valid CSS classname
// Support new-style instance-bound definitions. Old-style class-bound
// definitions have one widget "object" per widget per type/class of
// widget; the renderValue and resize methods on such widget objects
// take el and instance arguments, because the widget object can't
// store them. New-style instance-bound definitions have one widget
// object per widget instance; the definition that's passed in doesn't
// provide renderValue or resize methods at all, just the single method
// factory(el, width, height)
// which returns an object that has renderValue(x) and resize(w, h).
// This enables a far more natural programming style for the widget
// author, who can store per-instance state using either OO-style
// instance fields or functional-style closure variables (I guess this
// is in contrast to what can only be called C-style pseudo-OO which is
// what we required before).
if (definition.factory) {
definition = createLegacyDefinitionAdapter(definition);
}
if (!definition.renderValue) {
throw new Error("Widget must have a renderValue function");
}
// For static rendering (non-Shiny), use a simple widget registration
// scheme. We also use this scheme for Shiny apps/documents that also
// contain static widgets.
window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
// Merge defaults into the definition; don't mutate the original definition.
var staticBinding = extend({}, defaults, definition);
overrideMethod(staticBinding, "find", function(superfunc) {
return function(scope) {
var results = superfunc(scope);
// Filter out Shiny outputs, we only want the static kind
return filterByClass(results, "html-widget-output", false);
};
});
window.HTMLWidgets.widgets.push(staticBinding);
if (shinyMode) {
// Shiny is running. Register the definition with an output binding.
// The definition itself will not be the output binding, instead
// we will make an output binding object that delegates to the
// definition. This is because we foolishly used the same method
// name (renderValue) for htmlwidgets definition and Shiny bindings
// but they actually have quite different semantics (the Shiny
// bindings receive data that includes lots of metadata that it
// strips off before calling htmlwidgets renderValue). We can't
// just ignore the difference because in some widgets it's helpful
// to call this.renderValue() from inside of resize(), and if
// we're not delegating, then that call will go to the Shiny
// version instead of the htmlwidgets version.
// Merge defaults with definition, without mutating either.
var bindingDef = extend({}, defaults, definition);
// This object will be our actual Shiny binding.
var shinyBinding = new Shiny.OutputBinding();
// With a few exceptions, we'll want to simply use the bindingDef's
// version of methods if they are available, otherwise fall back to
// Shiny's defaults. NOTE: If Shiny's output bindings gain additional
// methods in the future, and we want them to be overrideable by
// HTMLWidget binding definitions, then we'll need to add them to this
// list.
delegateMethod(shinyBinding, bindingDef, "getId");
delegateMethod(shinyBinding, bindingDef, "onValueChange");
delegateMethod(shinyBinding, bindingDef, "onValueError");
delegateMethod(shinyBinding, bindingDef, "renderError");
delegateMethod(shinyBinding, bindingDef, "clearError");
delegateMethod(shinyBinding, bindingDef, "showProgress");
// The find, renderValue, and resize are handled differently, because we
// want to actually decorate the behavior of the bindingDef methods.
shinyBinding.find = function(scope) {
var results = bindingDef.find(scope);
// Only return elements that are Shiny outputs, not static ones
var dynamicResults = results.filter(".html-widget-output");
// It's possible that whatever caused Shiny to think there might be
// new dynamic outputs, also caused there to be new static outputs.
// Since there might be lots of different htmlwidgets bindings, we
// schedule execution for later--no need to staticRender multiple
// times.
if (results.length !== dynamicResults.length)
scheduleStaticRender();
return dynamicResults;
};
// Wrap renderValue to handle initialization, which unfortunately isn't
// supported natively by Shiny at the time of this writing.
shinyBinding.renderValue = function(el, data) {
Shiny.renderDependencies(data.deps);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var i = 0; data.evals && i < data.evals.length; i++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
}
if (!bindingDef.renderOnNullValue) {
if (data.x === null) {
el.style.visibility = "hidden";
return;
} else {
el.style.visibility = "inherit";
}
}
if (!elementData(el, "initialized")) {
initSizing(el);
elementData(el, "initialized", true);
if (bindingDef.initialize) {
var result = bindingDef.initialize(el, el.offsetWidth,
el.offsetHeight);
elementData(el, "init_result", result);
}
}
bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
};
// Only override resize if bindingDef implements it
if (bindingDef.resize) {
shinyBinding.resize = function(el, width, height) {
// Shiny can call resize before initialize/renderValue have been
// called, which doesn't make sense for widgets.
if (elementData(el, "initialized")) {
bindingDef.resize(el, width, height, elementData(el, "init_result"));
}
};
}
Shiny.outputBindings.register(shinyBinding, bindingDef.name);
}
};
var scheduleStaticRenderTimerId = null;
function scheduleStaticRender() {
if (!scheduleStaticRenderTimerId) {
scheduleStaticRenderTimerId = setTimeout(function() {
scheduleStaticRenderTimerId = null;
window.HTMLWidgets.staticRender();
}, 1);
}
}
// Render static widgets after the document finishes loading
// Statically render all elements that are of this widget's class
window.HTMLWidgets.staticRender = function() {
var bindings = window.HTMLWidgets.widgets || [];
forEach(bindings, function(binding) {
var matches = binding.find(document.documentElement);
forEach(matches, function(el) {
var sizeObj = initSizing(el, binding);
if (hasClass(el, "html-widget-static-bound"))
return;
el.className = el.className + " html-widget-static-bound";
var initResult;
if (binding.initialize) {
initResult = binding.initialize(el,
sizeObj ? sizeObj.getWidth() : el.offsetWidth,
sizeObj ? sizeObj.getHeight() : el.offsetHeight
);
elementData(el, "init_result", initResult);
}
if (binding.resize) {
var lastSize = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
var resizeHandler = function(e) {
var size = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
if (size.w === 0 && size.h === 0)
return;
if (size.w === lastSize.w && size.h === lastSize.h)
return;
lastSize = size;
binding.resize(el, size.w, size.h, initResult);
};
on(window, "resize", resizeHandler);
// This is needed for cases where we're running in a Shiny
// app, but the widget itself is not a Shiny output, but
// rather a simple static widget. One example of this is
// an rmarkdown document that has runtime:shiny and widget
// that isn't in a render function. Shiny only knows to
// call resize handlers for Shiny outputs, not for static
// widgets, so we do it ourselves.
if (window.jQuery) {
window.jQuery(document).on(
"shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
resizeHandler
);
window.jQuery(document).on(
"hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
resizeHandler
);
}
// This is needed for the specific case of ioslides, which
// flips slides between display:none and display:block.
// Ideally we would not have to have ioslide-specific code
// here, but rather have ioslides raise a generic event,
// but the rmarkdown package just went to CRAN so the
// window to getting that fixed may be long.
if (window.addEventListener) {
// It's OK to limit this to window.addEventListener
// browsers because ioslides itself only supports
// such browsers.
on(document, "slideenter", resizeHandler);
on(document, "slideleave", resizeHandler);
}
}
var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
if (scriptData) {
var data = JSON.parse(scriptData.textContent || scriptData.text);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var k = 0; data.evals && k < data.evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
}
binding.renderValue(el, data.x, initResult);
evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
}
});
});
invokePostRenderHandlers();
}
function has_jQuery3() {
if (!window.jQuery) {
return false;
}
var $version = window.jQuery.fn.jquery;
var $major_version = parseInt($version.split(".")[0]);
return $major_version >= 3;
}
/*
/ Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
/ on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
/ really means $(setTimeout(fn)).
/ https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
/
/ Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
/ one tick later than it did before, which means staticRender() is
/ called renderValue() earlier than (advanced) widget authors might be expecting.
/ https://github.com/rstudio/shiny/issues/2630
/
/ For a concrete example, leaflet has some methods (e.g., updateBounds)
/ which reference Shiny methods registered in initShiny (e.g., setInputValue).
/ Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
/ delay execution of those methods (until Shiny methods are ready)
/ https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
/
/ Ideally widget authors wouldn't need to use this setTimeout() hack that
/ leaflet uses to call Shiny methods on a staticRender(). In the long run,
/ the logic initShiny should be broken up so that method registration happens
/ right away, but binding happens later.
*/
function maybeStaticRenderLater() {
if (shinyMode && has_jQuery3()) {
window.jQuery(window.HTMLWidgets.staticRender);
} else {
window.HTMLWidgets.staticRender();
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
maybeStaticRenderLater();
}, false);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
maybeStaticRenderLater();
}
});
}
window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
// If no key, default to the first item
if (typeof(key) === "undefined")
key = 1;
var link = document.getElementById(depname + "-" + key + "-attachment");
if (!link) {
throw new Error("Attachment " + depname + "/" + key + " not found in document");
}
return link.getAttribute("href");
};
window.HTMLWidgets.dataframeToD3 = function(df) {
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
window.HTMLWidgets.transposeArray2D = function(array) {
if (array.length === 0) return array;
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
};
// Split value at splitChar, but allow splitChar to be escaped
// using escapeChar. Any other characters escaped by escapeChar
// will be included as usual (including escapeChar itself).
function splitWithEscape(value, splitChar, escapeChar) {
var results = [];
var escapeMode = false;
var currentResult = "";
for (var pos = 0; pos < value.length; pos++) {
if (!escapeMode) {
if (value[pos] === splitChar) {
results.push(currentResult);
currentResult = "";
} else if (value[pos] === escapeChar) {
escapeMode = true;
} else {
currentResult += value[pos];
}
} else {
currentResult += value[pos];
escapeMode = false;
}
}
if (currentResult !== "") {
results.push(currentResult);
}
return results;
}
// Function authored by Yihui/JJ Allaire
window.HTMLWidgets.evaluateStringMember = function(o, member) {
var parts = splitWithEscape(member, '.', '\\');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// part may be a character or 'numeric' member name
if (o !== null && typeof o === "object" && part in o) {
if (i == (l - 1)) { // if we are at the end of the line then evalulate
if (typeof o[part] === "string")
o[part] = tryEval(o[part]);
} else { // otherwise continue to next embedded object
o = o[part];
}
}
}
};
// Retrieve the HTMLWidget instance (i.e. the return value of an
// HTMLWidget binding's initialize() or factory() function)
// associated with an element, or null if none.
window.HTMLWidgets.getInstance = function(el) {
return elementData(el, "init_result");
};
// Finds the first element in the scope that matches the selector,
// and returns the HTMLWidget instance (i.e. the return value of
// an HTMLWidget binding's initialize() or factory() function)
// associated with that element, if any. If no element matches the
// selector, or the first matching element has no HTMLWidget
// instance associated with it, then null is returned.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.find = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var el = scope.querySelector(selector);
if (el === null) {
return null;
} else {
return window.HTMLWidgets.getInstance(el);
}
};
// Finds all elements in the scope that match the selector, and
// returns the HTMLWidget instances (i.e. the return values of
// an HTMLWidget binding's initialize() or factory() function)
// associated with the elements, in an array. If elements that
// match the selector don't have an associated HTMLWidget
// instance, the returned array will contain nulls.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.findAll = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var nodes = scope.querySelectorAll(selector);
var results = [];
for (var i = 0; i < nodes.length; i++) {
results.push(window.HTMLWidgets.getInstance(nodes[i]));
}
return results;
};
var postRenderHandlers = [];
function invokePostRenderHandlers() {
while (postRenderHandlers.length) {
var handler = postRenderHandlers.shift();
if (handler) {
handler();
}
}
}
// Register the given callback function to be invoked after the
// next time static widgets are rendered.
window.HTMLWidgets.addPostRenderHandler = function(callback) {
postRenderHandlers.push(callback);
};
// Takes a new-style instance-bound definition, and returns an
// old-style class-bound definition. This saves us from having
// to rewrite all the logic in this file to accomodate both
// types of definitions.
function createLegacyDefinitionAdapter(defn) {
var result = {
name: defn.name,
type: defn.type,
initialize: function(el, width, height) {
return defn.factory(el, width, height);
},
renderValue: function(el, x, instance) {
return instance.renderValue(x);
},
resize: function(el, width, height, instance) {
return instance.resize(width, height);
}
};
if (defn.find)
result.find = defn.find;
if (defn.renderError)
result.renderError = defn.renderError;
if (defn.clearError)
result.clearError = defn.clearError;
return result;
}
})();

View File

@ -1,289 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<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>Options &amp; styles for lines • apexcharter</title>
<!-- jquery --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script><!-- Bootstrap --><link href="../css/theme.css" rel="stylesheet">
<!-- Font --><link href="../css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- Particles --><script src="../js/particles.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></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="Options &amp; styles for lines">
<meta property="og:description" content="">
<meta name="twitter:card" content="summary">
<!-- 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-article">
<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.3.990</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.3.990</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/labs.html">Labs: title, subtitle &amp; axis</a>
</li>
<li>
<a href="../articles/lines.html">Options &amp; styles for lines</a>
</li>
<li>
<a href="../articles/shiny-integration.html">Shiny integration</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><script src="lines_files/htmlwidgets-1.5.1/htmlwidgets.js"></script><script src="lines_files/apexcharts-3.17.1/apexcharts.min.js"></script><script src="lines_files/d3-format-1.4.2/d3-format.min.js"></script><script src="lines_files/apexcharter-binding-0.1.3.990/apexcharter.js"></script><div class="row">
<div class="col-md-9 contents">
<div class="page-header toc-ignore">
<h1>Options &amp; styles for lines</h1>
<small class="dont-index">Source: <a href="https://github.com/dreamRs/apexcharter/blob/master/vignettes/lines.Rmd"><code>vignettes/lines.Rmd</code></a></small>
<div class="hidden name"><code>lines.Rmd</code></div>
</div>
<div class="sourceCode" id="cb1"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb1-1" title="1"><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span>(apexcharter)</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span>(dplyr)</a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4"><span class="co"># economics dataset from ggplot2</span></a>
<a class="sourceLine" id="cb1-5" title="5"><span class="kw"><a href="https://rdrr.io/r/utils/data.html">data</a></span>(<span class="st">"economics"</span>, <span class="dt">package =</span> <span class="st">"ggplot2"</span>)</a>
<a class="sourceLine" id="cb1-6" title="6">economics &lt;-<span class="st"> </span><span class="kw"><a href="https://rdrr.io/r/utils/head.html">tail</a></span>(economics, <span class="dv">50</span>)</a>
<a class="sourceLine" id="cb1-7" title="7"></a>
<a class="sourceLine" id="cb1-8" title="8"><span class="kw"><a href="https://rdrr.io/r/utils/data.html">data</a></span>(<span class="st">"economics_long"</span>, <span class="dt">package =</span> <span class="st">"ggplot2"</span>)</a>
<a class="sourceLine" id="cb1-9" title="9">economics_long &lt;-<span class="st"> </span>economics_long <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb1-10" title="10"><span class="st"> </span><span class="kw"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span>(variable <span class="op">%in%</span><span class="st"> </span><span class="kw"><a href="https://rdrr.io/r/base/c.html">c</a></span>(<span class="st">"pce"</span>, <span class="st">"pop"</span>)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb1-11" title="11"><span class="st"> </span><span class="kw">group_by</span>(variable) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb1-12" title="12"><span class="st"> </span><span class="kw">slice</span>(<span class="kw"><a href="https://rdrr.io/r/utils/head.html">tail</a></span>(<span class="kw">row_number</span>(), <span class="dv">20</span>))</a></code></pre></div>
<div id="type-of-line" class="section level2">
<h2 class="hasAnchor">
<a href="#type-of-line" class="anchor"></a>Type of line</h2>
<p>Classic line:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb2-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed))</a></code></pre></div>
<div id="htmlwidget-890e054d1f2a1a8b013d" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-890e054d1f2a1a8b013d">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":2},"xaxis":{"type":"datetime"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script><p>Spline curve:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb3-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_stroke.html">ax_stroke</a></span>(<span class="dt">curve =</span> <span class="st">"smooth"</span>)</a></code></pre></div>
<div id="htmlwidget-951690ff55c55a1c48c0" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-951690ff55c55a1c48c0">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"smooth","width":2},"xaxis":{"type":"datetime"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script><p>Steps chart:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb4-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_stroke.html">ax_stroke</a></span>(<span class="dt">curve =</span> <span class="st">"stepline"</span>)</a></code></pre></div>
<div id="htmlwidget-72ff10ab3342367dbd1a" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-72ff10ab3342367dbd1a">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"stepline","width":2},"xaxis":{"type":"datetime"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script>
</div>
<div id="line-appearance" class="section level2">
<h2 class="hasAnchor">
<a href="#line-appearance" class="anchor"></a>Line appearance</h2>
<p>Color line with gradient:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb5-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_fill.html">ax_fill</a></span>(</a>
<a class="sourceLine" id="cb5-3" title="3"> <span class="dt">type =</span> <span class="st">"gradient"</span>,</a>
<a class="sourceLine" id="cb5-4" title="4"> <span class="dt">gradient =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(</a>
<a class="sourceLine" id="cb5-5" title="5"> <span class="dt">shade =</span> <span class="st">"dark"</span>,</a>
<a class="sourceLine" id="cb5-6" title="6"> <span class="dt">gradientToColors =</span> <span class="kw"><a href="https://rdrr.io/r/base/list.html">list</a></span>(<span class="st">"#FDD835"</span>),</a>
<a class="sourceLine" id="cb5-7" title="7"> <span class="dt">shadeIntensity =</span> <span class="dv">1</span>,</a>
<a class="sourceLine" id="cb5-8" title="8"> <span class="dt">type =</span> <span class="st">"horizontal"</span>,</a>
<a class="sourceLine" id="cb5-9" title="9"> <span class="dt">opacityFrom =</span> <span class="dv">1</span>,</a>
<a class="sourceLine" id="cb5-10" title="10"> <span class="dt">opacityTo =</span> <span class="dv">1</span>,</a>
<a class="sourceLine" id="cb5-11" title="11"> <span class="dt">stops =</span> <span class="kw"><a href="https://rdrr.io/r/base/c.html">c</a></span>(<span class="dv">0</span>, <span class="dv">100</span>, <span class="dv">100</span>, <span class="dv">100</span>)</a>
<a class="sourceLine" id="cb5-12" title="12"> )</a>
<a class="sourceLine" id="cb5-13" title="13"> )</a></code></pre></div>
<div id="htmlwidget-211a404ab8f358c920ee" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-211a404ab8f358c920ee">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":2},"xaxis":{"type":"datetime"},"fill":{"type":"gradient","gradient":{"shade":"dark","gradientToColors":["#FDD835"],"shadeIntensity":1,"type":"horizontal","opacityFrom":1,"opacityTo":1,"stops":[0,100,100,100]}}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script><p>Solid area color:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb6-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"area"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb6-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_fill.html">ax_fill</a></span>(<span class="dt">type =</span> <span class="st">"solid"</span>, <span class="dt">opacity =</span> <span class="dv">1</span>)</a></code></pre></div>
<div id="htmlwidget-21b27bdae74d6d197d22" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-21b27bdae74d6d197d22">{"x":{"ax_opts":{"chart":{"type":"area"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":2},"xaxis":{"type":"datetime"},"fill":{"type":"solid","opacity":1}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script><p>Line width:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb7-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb7-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_stroke.html">ax_stroke</a></span>(<span class="dt">width =</span> <span class="dv">1</span>)</a></code></pre></div>
<div id="htmlwidget-02d0344537e3c3719e50" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-02d0344537e3c3719e50">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":1},"xaxis":{"type":"datetime"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script><p>Dotted line</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb8-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb8-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_stroke.html">ax_stroke</a></span>(<span class="dt">dashArray =</span> <span class="dv">6</span>)</a></code></pre></div>
<div id="htmlwidget-f1ff676641bfbab493ca" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-f1ff676641bfbab493ca">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2011-03-01').getTime()",21.5],["new Date('2011-04-01').getTime()",20.9],["new Date('2011-05-01').getTime()",21.6],["new Date('2011-06-01').getTime()",22.4],["new Date('2011-07-01').getTime()",22],["new Date('2011-08-01').getTime()",22.4],["new Date('2011-09-01').getTime()",22],["new Date('2011-10-01').getTime()",20.6],["new Date('2011-11-01').getTime()",20.8],["new Date('2011-12-01').getTime()",20.5],["new Date('2012-01-01').getTime()",20.8],["new Date('2012-02-01').getTime()",19.7],["new Date('2012-03-01').getTime()",19.2],["new Date('2012-04-01').getTime()",19.1],["new Date('2012-05-01').getTime()",19.9],["new Date('2012-06-01').getTime()",20.4],["new Date('2012-07-01').getTime()",17.5],["new Date('2012-08-01').getTime()",18.4],["new Date('2012-09-01').getTime()",18.8],["new Date('2012-10-01').getTime()",19.9],["new Date('2012-11-01').getTime()",18.6],["new Date('2012-12-01').getTime()",17.7],["new Date('2013-01-01').getTime()",15.8],["new Date('2013-02-01').getTime()",17.2],["new Date('2013-03-01').getTime()",17.6],["new Date('2013-04-01').getTime()",17.1],["new Date('2013-05-01').getTime()",17.1],["new Date('2013-06-01').getTime()",17],["new Date('2013-07-01').getTime()",16.2],["new Date('2013-08-01').getTime()",16.5],["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":2,"dashArray":6},"xaxis":{"type":"datetime"}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.0.data.20.0","ax_opts.series.0.data.21.0","ax_opts.series.0.data.22.0","ax_opts.series.0.data.23.0","ax_opts.series.0.data.24.0","ax_opts.series.0.data.25.0","ax_opts.series.0.data.26.0","ax_opts.series.0.data.27.0","ax_opts.series.0.data.28.0","ax_opts.series.0.data.29.0","ax_opts.series.0.data.30.0","ax_opts.series.0.data.31.0","ax_opts.series.0.data.32.0","ax_opts.series.0.data.33.0","ax_opts.series.0.data.34.0","ax_opts.series.0.data.35.0","ax_opts.series.0.data.36.0","ax_opts.series.0.data.37.0","ax_opts.series.0.data.38.0","ax_opts.series.0.data.39.0","ax_opts.series.0.data.40.0","ax_opts.series.0.data.41.0","ax_opts.series.0.data.42.0","ax_opts.series.0.data.43.0","ax_opts.series.0.data.44.0","ax_opts.series.0.data.45.0","ax_opts.series.0.data.46.0","ax_opts.series.0.data.47.0","ax_opts.series.0.data.48.0","ax_opts.series.0.data.49.0"],"jsHooks":[]}</script>
</div>
<div id="markers" class="section level2">
<h2 class="hasAnchor">
<a href="#markers" class="anchor"></a>Markers</h2>
<p>Add points to line :</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb9-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> <span class="kw"><a href="https://rdrr.io/r/utils/head.html">tail</a></span>(economics, <span class="dv">20</span>), <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb9-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_markers.html">ax_markers</a></span>(<span class="dt">size =</span> <span class="dv">6</span>)</a></code></pre></div>
<div id="htmlwidget-b5c15854133d95a845b9" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-b5c15854133d95a845b9">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":2},"xaxis":{"type":"datetime"},"markers":{"size":6}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0"],"jsHooks":[]}</script><p>Add labels over points</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb10-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> <span class="kw"><a href="https://rdrr.io/r/utils/head.html">tail</a></span>(economics, <span class="dv">20</span>), <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> uempmed)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb10-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_markers.html">ax_markers</a></span>(<span class="dt">size =</span> <span class="dv">6</span>) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb10-3" title="3"><span class="st"> </span><span class="kw"><a href="../reference/ax_dataLabels.html">ax_dataLabels</a></span>(<span class="dt">enabled =</span> <span class="ot">TRUE</span>)</a></code></pre></div>
<div id="htmlwidget-2ff90228648b68d661cd" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-2ff90228648b68d661cd">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"uempmed","data":[["new Date('2013-09-01').getTime()",16.5],["new Date('2013-10-01').getTime()",16.3],["new Date('2013-11-01').getTime()",17.1],["new Date('2013-12-01').getTime()",17.3],["new Date('2014-01-01').getTime()",15.4],["new Date('2014-02-01').getTime()",15.9],["new Date('2014-03-01').getTime()",15.8],["new Date('2014-04-01').getTime()",15.7],["new Date('2014-05-01').getTime()",14.6],["new Date('2014-06-01').getTime()",13.8],["new Date('2014-07-01').getTime()",13.1],["new Date('2014-08-01').getTime()",12.9],["new Date('2014-09-01').getTime()",13.4],["new Date('2014-10-01').getTime()",13.6],["new Date('2014-11-01').getTime()",13],["new Date('2014-12-01').getTime()",12.9],["new Date('2015-01-01').getTime()",13.2],["new Date('2015-02-01').getTime()",12.9],["new Date('2015-03-01').getTime()",12],["new Date('2015-04-01').getTime()",11.5]]}],"dataLabels":{"enabled":true},"stroke":{"curve":"straight","width":2},"xaxis":{"type":"datetime"},"markers":{"size":6}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0"],"jsHooks":[]}</script>
</div>
<div id="multiple-lines" class="section level2">
<h2 class="hasAnchor">
<a href="#multiple-lines" class="anchor"></a>Multiple lines</h2>
<p>You can use vectors of parameters to custom series separately:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb11-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics_long, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> value01, <span class="dt">group =</span> variable)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb11-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_yaxis.html">ax_yaxis</a></span>(<span class="dt">decimalsInFloat =</span> <span class="dv">2</span>) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb11-3" title="3"><span class="st"> </span><span class="kw"><a href="../reference/ax_markers.html">ax_markers</a></span>(<span class="dt">size =</span> <span class="kw"><a href="https://rdrr.io/r/base/c.html">c</a></span>(<span class="dv">3</span>, <span class="dv">6</span>)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb11-4" title="4"><span class="st"> </span><span class="kw"><a href="../reference/ax_stroke.html">ax_stroke</a></span>(<span class="dt">width =</span> <span class="kw"><a href="https://rdrr.io/r/base/c.html">c</a></span>(<span class="dv">1</span>, <span class="dv">3</span>))</a></code></pre></div>
<div id="htmlwidget-03d1474a75964c2a95cc" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-03d1474a75964c2a95cc">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"pce","data":[["new Date('2013-09-01').getTime()",0.92924677636026],["new Date('2013-10-01').getTime()",0.933773134481608],["new Date('2013-11-01').getTime()",0.939574402546397],["new Date('2013-12-01').getTime()",0.942167004646148],["new Date('2014-01-01').getTime()",0.941704956747183],["new Date('2014-02-01').getTime()",0.946299766409118],["new Date('2014-03-01').getTime()",0.952871114305516],["new Date('2014-04-01').getTime()",0.957970754079284],["new Date('2014-05-01').getTime()",0.961889604777918],["new Date('2014-06-01').getTime()",0.967759324383294],["new Date('2014-07-01').getTime()",0.971481376902739],["new Date('2014-08-01').getTime()",0.978651675779278],["new Date('2014-09-01').getTime()",0.979772569756398],["new Date('2014-10-01').getTime()",0.985385596084572],["new Date('2014-11-01').getTime()",0.987815625775428],["new Date('2014-12-01').getTime()",0.988722608688212],["new Date('2015-01-01').getTime()",0.987353577876462],["new Date('2015-02-01').getTime()",0.990468122973193],["new Date('2015-03-01').getTime()",0.99696246288643],["new Date('2015-04-01').getTime()",1]]},{"name":"pop","data":[["new Date('2013-09-01').getTime()",0.970448177482025],["new Date('2013-10-01').getTime()",0.972224366782906],["new Date('2013-11-01').getTime()",0.97391518362249],["new Date('2013-12-01').getTime()",0.975423315392571],["new Date('2014-01-01').getTime()",0.976921972290395],["new Date('2014-02-01').getTime()",0.97823645673634],["new Date('2014-03-01').getTime()",0.97957855225842],["new Date('2014-04-01').getTime()",0.980992099657577],["new Date('2014-05-01').getTime()",0.982473622896551],["new Date('2014-06-01').getTime()",0.984073150615668],["new Date('2014-07-01').getTime()",0.985702006885595],["new Date('2014-08-01').getTime()",0.987603703319152],["new Date('2014-09-01').getTime()",0.989506155770269],["new Date('2014-10-01').getTime()",0.991383363808922],["new Date('2014-11-01').getTime()",0.993112959418826],["new Date('2014-12-01').getTime()",0.994608132061805],["new Date('2015-01-01').getTime()",0.996107750416745],["new Date('2015-02-01').getTime()",0.997306408041825],["new Date('2015-03-01').getTime()",0.998590610697427],["new Date('2015-04-01').getTime()",1]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":[1,3]},"xaxis":{"type":"datetime"},"yaxis":{"decimalsInFloat":2},"markers":{"size":[3,6]}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.1.data.0.0","ax_opts.series.1.data.1.0","ax_opts.series.1.data.2.0","ax_opts.series.1.data.3.0","ax_opts.series.1.data.4.0","ax_opts.series.1.data.5.0","ax_opts.series.1.data.6.0","ax_opts.series.1.data.7.0","ax_opts.series.1.data.8.0","ax_opts.series.1.data.9.0","ax_opts.series.1.data.10.0","ax_opts.series.1.data.11.0","ax_opts.series.1.data.12.0","ax_opts.series.1.data.13.0","ax_opts.series.1.data.14.0","ax_opts.series.1.data.15.0","ax_opts.series.1.data.16.0","ax_opts.series.1.data.17.0","ax_opts.series.1.data.18.0","ax_opts.series.1.data.19.0"],"jsHooks":[]}</script><div class="sourceCode" id="cb12"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb12-1" title="1"><span class="kw"><a href="../reference/apex.html">apex</a></span>(<span class="dt">data =</span> economics_long, <span class="dt">type =</span> <span class="st">"line"</span>, <span class="dt">mapping =</span> <span class="kw"><a href="../reference/apexcharter-exports.html">aes</a></span>(<span class="dt">x =</span> date, <span class="dt">y =</span> value01, <span class="dt">group =</span> variable)) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb12-2" title="2"><span class="st"> </span><span class="kw"><a href="../reference/ax_yaxis.html">ax_yaxis</a></span>(<span class="dt">decimalsInFloat =</span> <span class="dv">2</span>) <span class="op">%&gt;%</span><span class="st"> </span></a>
<a class="sourceLine" id="cb12-3" title="3"><span class="st"> </span><span class="kw"><a href="../reference/ax_stroke.html">ax_stroke</a></span>(<span class="dt">dashArray =</span> <span class="kw"><a href="https://rdrr.io/r/base/c.html">c</a></span>(<span class="dv">8</span>, <span class="dv">5</span>))</a></code></pre></div>
<div id="htmlwidget-86bdd5de9893d348269a" style="width:100%;height:350px;" class="apexcharter html-widget"></div>
<script type="application/json" data-for="htmlwidget-86bdd5de9893d348269a">{"x":{"ax_opts":{"chart":{"type":"line"},"series":[{"name":"pce","data":[["new Date('2013-09-01').getTime()",0.92924677636026],["new Date('2013-10-01').getTime()",0.933773134481608],["new Date('2013-11-01').getTime()",0.939574402546397],["new Date('2013-12-01').getTime()",0.942167004646148],["new Date('2014-01-01').getTime()",0.941704956747183],["new Date('2014-02-01').getTime()",0.946299766409118],["new Date('2014-03-01').getTime()",0.952871114305516],["new Date('2014-04-01').getTime()",0.957970754079284],["new Date('2014-05-01').getTime()",0.961889604777918],["new Date('2014-06-01').getTime()",0.967759324383294],["new Date('2014-07-01').getTime()",0.971481376902739],["new Date('2014-08-01').getTime()",0.978651675779278],["new Date('2014-09-01').getTime()",0.979772569756398],["new Date('2014-10-01').getTime()",0.985385596084572],["new Date('2014-11-01').getTime()",0.987815625775428],["new Date('2014-12-01').getTime()",0.988722608688212],["new Date('2015-01-01').getTime()",0.987353577876462],["new Date('2015-02-01').getTime()",0.990468122973193],["new Date('2015-03-01').getTime()",0.99696246288643],["new Date('2015-04-01').getTime()",1]]},{"name":"pop","data":[["new Date('2013-09-01').getTime()",0.970448177482025],["new Date('2013-10-01').getTime()",0.972224366782906],["new Date('2013-11-01').getTime()",0.97391518362249],["new Date('2013-12-01').getTime()",0.975423315392571],["new Date('2014-01-01').getTime()",0.976921972290395],["new Date('2014-02-01').getTime()",0.97823645673634],["new Date('2014-03-01').getTime()",0.97957855225842],["new Date('2014-04-01').getTime()",0.980992099657577],["new Date('2014-05-01').getTime()",0.982473622896551],["new Date('2014-06-01').getTime()",0.984073150615668],["new Date('2014-07-01').getTime()",0.985702006885595],["new Date('2014-08-01').getTime()",0.987603703319152],["new Date('2014-09-01').getTime()",0.989506155770269],["new Date('2014-10-01').getTime()",0.991383363808922],["new Date('2014-11-01').getTime()",0.993112959418826],["new Date('2014-12-01').getTime()",0.994608132061805],["new Date('2015-01-01').getTime()",0.996107750416745],["new Date('2015-02-01').getTime()",0.997306408041825],["new Date('2015-03-01').getTime()",0.998590610697427],["new Date('2015-04-01').getTime()",1]]}],"dataLabels":{"enabled":false},"stroke":{"curve":"straight","width":2,"dashArray":[8,5]},"xaxis":{"type":"datetime"},"yaxis":{"decimalsInFloat":2}},"auto_update":{"series_animate":true,"update_options":false,"options_animate":true,"options_redrawPaths":false}},"evals":["ax_opts.series.0.data.0.0","ax_opts.series.0.data.1.0","ax_opts.series.0.data.2.0","ax_opts.series.0.data.3.0","ax_opts.series.0.data.4.0","ax_opts.series.0.data.5.0","ax_opts.series.0.data.6.0","ax_opts.series.0.data.7.0","ax_opts.series.0.data.8.0","ax_opts.series.0.data.9.0","ax_opts.series.0.data.10.0","ax_opts.series.0.data.11.0","ax_opts.series.0.data.12.0","ax_opts.series.0.data.13.0","ax_opts.series.0.data.14.0","ax_opts.series.0.data.15.0","ax_opts.series.0.data.16.0","ax_opts.series.0.data.17.0","ax_opts.series.0.data.18.0","ax_opts.series.0.data.19.0","ax_opts.series.1.data.0.0","ax_opts.series.1.data.1.0","ax_opts.series.1.data.2.0","ax_opts.series.1.data.3.0","ax_opts.series.1.data.4.0","ax_opts.series.1.data.5.0","ax_opts.series.1.data.6.0","ax_opts.series.1.data.7.0","ax_opts.series.1.data.8.0","ax_opts.series.1.data.9.0","ax_opts.series.1.data.10.0","ax_opts.series.1.data.11.0","ax_opts.series.1.data.12.0","ax_opts.series.1.data.13.0","ax_opts.series.1.data.14.0","ax_opts.series.1.data.15.0","ax_opts.series.1.data.16.0","ax_opts.series.1.data.17.0","ax_opts.series.1.data.18.0","ax_opts.series.1.data.19.0"],"jsHooks":[]}</script>
</div>
</div>
<div class="col-md-3 hidden-xs hidden-sm" id="sidebar">
<div id="tocnav">
<h2 class="hasAnchor">
<a href="#tocnav" class="anchor"></a>Contents</h2>
<ul class="nav nav-pills nav-stacked">
<li><a href="#type-of-line">Type of line</a></li>
<li><a href="#line-appearance">Line appearance</a></li>
<li><a href="#markers">Markers</a></li>
<li><a href="#multiple-lines">Multiple lines</a></li>
</ul>
</div>
</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.4.1.</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,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);
}
});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,903 +0,0 @@
(function() {
// If window.HTMLWidgets is already defined, then use it; otherwise create a
// new object. This allows preceding code to set options that affect the
// initialization process (though none currently exist).
window.HTMLWidgets = window.HTMLWidgets || {};
// See if we're running in a viewer pane. If not, we're in a web browser.
var viewerMode = window.HTMLWidgets.viewerMode =
/\bviewer_pane=1\b/.test(window.location);
// See if we're running in Shiny mode. If not, it's a static document.
// Note that static widgets can appear in both Shiny and static modes, but
// obviously, Shiny widgets can only appear in Shiny apps/documents.
var shinyMode = window.HTMLWidgets.shinyMode =
typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
// We can't count on jQuery being available, so we implement our own
// version if necessary.
function querySelectorAll(scope, selector) {
if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
return scope.find(selector);
}
if (scope.querySelectorAll) {
return scope.querySelectorAll(selector);
}
}
function asArray(value) {
if (value === null)
return [];
if ($.isArray(value))
return value;
return [value];
}
// Implement jQuery's extend
function extend(target /*, ... */) {
if (arguments.length == 1) {
return target;
}
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
// IE8 doesn't support Array.forEach.
function forEach(values, callback, thisArg) {
if (values.forEach) {
values.forEach(callback, thisArg);
} else {
for (var i = 0; i < values.length; i++) {
callback.call(thisArg, values[i], i, values);
}
}
}
// Replaces the specified method with the return value of funcSource.
//
// Note that funcSource should not BE the new method, it should be a function
// that RETURNS the new method. funcSource receives a single argument that is
// the overridden method, it can be called from the new method. The overridden
// method can be called like a regular function, it has the target permanently
// bound to it so "this" will work correctly.
function overrideMethod(target, methodName, funcSource) {
var superFunc = target[methodName] || function() {};
var superFuncBound = function() {
return superFunc.apply(target, arguments);
};
target[methodName] = funcSource(superFuncBound);
}
// Add a method to delegator that, when invoked, calls
// delegatee.methodName. If there is no such method on
// the delegatee, but there was one on delegator before
// delegateMethod was called, then the original version
// is invoked instead.
// For example:
//
// var a = {
// method1: function() { console.log('a1'); }
// method2: function() { console.log('a2'); }
// };
// var b = {
// method1: function() { console.log('b1'); }
// };
// delegateMethod(a, b, "method1");
// delegateMethod(a, b, "method2");
// a.method1();
// a.method2();
//
// The output would be "b1", "a2".
function delegateMethod(delegator, delegatee, methodName) {
var inherited = delegator[methodName];
delegator[methodName] = function() {
var target = delegatee;
var method = delegatee[methodName];
// The method doesn't exist on the delegatee. Instead,
// call the method on the delegator, if it exists.
if (!method) {
target = delegator;
method = inherited;
}
if (method) {
return method.apply(target, arguments);
}
};
}
// Implement a vague facsimilie of jQuery's data method
function elementData(el, name, value) {
if (arguments.length == 2) {
return el["htmlwidget_data_" + name];
} else if (arguments.length == 3) {
el["htmlwidget_data_" + name] = value;
return el;
} else {
throw new Error("Wrong number of arguments for elementData: " +
arguments.length);
}
}
// http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function hasClass(el, className) {
var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
return re.test(el.className);
}
// elements - array (or array-like object) of HTML elements
// className - class name to test for
// include - if true, only return elements with given className;
// if false, only return elements *without* given className
function filterByClass(elements, className, include) {
var results = [];
for (var i = 0; i < elements.length; i++) {
if (hasClass(elements[i], className) == include)
results.push(elements[i]);
}
return results;
}
function on(obj, eventName, func) {
if (obj.addEventListener) {
obj.addEventListener(eventName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(eventName, func);
}
}
function off(obj, eventName, func) {
if (obj.removeEventListener)
obj.removeEventListener(eventName, func, false);
else if (obj.detachEvent) {
obj.detachEvent(eventName, func);
}
}
// Translate array of values to top/right/bottom/left, as usual with
// the "padding" CSS property
// https://developer.mozilla.org/en-US/docs/Web/CSS/padding
function unpackPadding(value) {
if (typeof(value) === "number")
value = [value];
if (value.length === 1) {
return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
}
if (value.length === 2) {
return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
}
if (value.length === 3) {
return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
}
if (value.length === 4) {
return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
}
}
// Convert an unpacked padding object to a CSS value
function paddingToCss(paddingObj) {
return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
}
// Makes a number suitable for CSS
function px(x) {
if (typeof(x) === "number")
return x + "px";
else
return x;
}
// Retrieves runtime widget sizing information for an element.
// The return value is either null, or an object with fill, padding,
// defaultWidth, defaultHeight fields.
function sizingPolicy(el) {
var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
if (!sizingEl)
return null;
var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
if (viewerMode) {
return sp.viewer;
} else {
return sp.browser;
}
}
// @param tasks Array of strings (or falsy value, in which case no-op).
// Each element must be a valid JavaScript expression that yields a
// function. Or, can be an array of objects with "code" and "data"
// properties; in this case, the "code" property should be a string
// of JS that's an expr that yields a function, and "data" should be
// an object that will be added as an additional argument when that
// function is called.
// @param target The object that will be "this" for each function
// execution.
// @param args Array of arguments to be passed to the functions. (The
// same arguments will be passed to all functions.)
function evalAndRun(tasks, target, args) {
if (tasks) {
forEach(tasks, function(task) {
var theseArgs = args;
if (typeof(task) === "object") {
theseArgs = theseArgs.concat([task.data]);
task = task.code;
}
var taskFunc = tryEval(task);
if (typeof(taskFunc) !== "function") {
throw new Error("Task must be a function! Source:\n" + task);
}
taskFunc.apply(target, theseArgs);
});
}
}
// Attempt eval() both with and without enclosing in parentheses.
// Note that enclosing coerces a function declaration into
// an expression that eval() can parse
// (otherwise, a SyntaxError is thrown)
function tryEval(code) {
var result = null;
try {
result = eval(code);
} catch(error) {
if (!error instanceof SyntaxError) {
throw error;
}
try {
result = eval("(" + code + ")");
} catch(e) {
if (e instanceof SyntaxError) {
throw error;
} else {
throw e;
}
}
}
return result;
}
function initSizing(el) {
var sizing = sizingPolicy(el);
if (!sizing)
return;
var cel = document.getElementById("htmlwidget_container");
if (!cel)
return;
if (typeof(sizing.padding) !== "undefined") {
document.body.style.margin = "0";
document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
}
if (sizing.fill) {
document.body.style.overflow = "hidden";
document.body.style.width = "100%";
document.body.style.height = "100%";
document.documentElement.style.width = "100%";
document.documentElement.style.height = "100%";
if (cel) {
cel.style.position = "absolute";
var pad = unpackPadding(sizing.padding);
cel.style.top = pad.top + "px";
cel.style.right = pad.right + "px";
cel.style.bottom = pad.bottom + "px";
cel.style.left = pad.left + "px";
el.style.width = "100%";
el.style.height = "100%";
}
return {
getWidth: function() { return cel.offsetWidth; },
getHeight: function() { return cel.offsetHeight; }
};
} else {
el.style.width = px(sizing.width);
el.style.height = px(sizing.height);
return {
getWidth: function() { return el.offsetWidth; },
getHeight: function() { return el.offsetHeight; }
};
}
}
// Default implementations for methods
var defaults = {
find: function(scope) {
return querySelectorAll(scope, "." + this.name);
},
renderError: function(el, err) {
var $el = $(el);
this.clearError(el);
// Add all these error classes, as Shiny does
var errClass = "shiny-output-error";
if (err.type !== null) {
// use the classes of the error condition as CSS class names
errClass = errClass + " " + $.map(asArray(err.type), function(type) {
return errClass + "-" + type;
}).join(" ");
}
errClass = errClass + " htmlwidgets-error";
// Is el inline or block? If inline or inline-block, just display:none it
// and add an inline error.
var display = $el.css("display");
$el.data("restore-display-mode", display);
if (display === "inline" || display === "inline-block") {
$el.hide();
if (err.message !== "") {
var errorSpan = $("<span>").addClass(errClass);
errorSpan.text(err.message);
$el.after(errorSpan);
}
} else if (display === "block") {
// If block, add an error just after the el, set visibility:none on the
// el, and position the error to be on top of the el.
// Mark it with a unique ID and CSS class so we can remove it later.
$el.css("visibility", "hidden");
if (err.message !== "") {
var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
// setting width can push out the page size, forcing otherwise
// unnecessary scrollbars to appear and making it impossible for
// the element to shrink; so use max-width instead
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
errorDiv.text(err.message);
$el.after(errorDiv);
// Really dumb way to keep the size/position of the error in sync with
// the parent element as the window is resized or whatever.
var intId = setInterval(function() {
if (!errorDiv[0].parentElement) {
clearInterval(intId);
return;
}
errorDiv
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
}, 500);
}
}
},
clearError: function(el) {
var $el = $(el);
var display = $el.data("restore-display-mode");
$el.data("restore-display-mode", null);
if (display === "inline" || display === "inline-block") {
if (display)
$el.css("display", display);
$(el.nextSibling).filter(".htmlwidgets-error").remove();
} else if (display === "block"){
$el.css("visibility", "inherit");
$(el.nextSibling).filter(".htmlwidgets-error").remove();
}
},
sizing: {}
};
// Called by widget bindings to register a new type of widget. The definition
// object can contain the following properties:
// - name (required) - A string indicating the binding name, which will be
// used by default as the CSS classname to look for.
// - initialize (optional) - A function(el) that will be called once per
// widget element; if a value is returned, it will be passed as the third
// value to renderValue.
// - renderValue (required) - A function(el, data, initValue) that will be
// called with data. Static contexts will cause this to be called once per
// element; Shiny apps will cause this to be called multiple times per
// element, as the data changes.
window.HTMLWidgets.widget = function(definition) {
if (!definition.name) {
throw new Error("Widget must have a name");
}
if (!definition.type) {
throw new Error("Widget must have a type");
}
// Currently we only support output widgets
if (definition.type !== "output") {
throw new Error("Unrecognized widget type '" + definition.type + "'");
}
// TODO: Verify that .name is a valid CSS classname
// Support new-style instance-bound definitions. Old-style class-bound
// definitions have one widget "object" per widget per type/class of
// widget; the renderValue and resize methods on such widget objects
// take el and instance arguments, because the widget object can't
// store them. New-style instance-bound definitions have one widget
// object per widget instance; the definition that's passed in doesn't
// provide renderValue or resize methods at all, just the single method
// factory(el, width, height)
// which returns an object that has renderValue(x) and resize(w, h).
// This enables a far more natural programming style for the widget
// author, who can store per-instance state using either OO-style
// instance fields or functional-style closure variables (I guess this
// is in contrast to what can only be called C-style pseudo-OO which is
// what we required before).
if (definition.factory) {
definition = createLegacyDefinitionAdapter(definition);
}
if (!definition.renderValue) {
throw new Error("Widget must have a renderValue function");
}
// For static rendering (non-Shiny), use a simple widget registration
// scheme. We also use this scheme for Shiny apps/documents that also
// contain static widgets.
window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
// Merge defaults into the definition; don't mutate the original definition.
var staticBinding = extend({}, defaults, definition);
overrideMethod(staticBinding, "find", function(superfunc) {
return function(scope) {
var results = superfunc(scope);
// Filter out Shiny outputs, we only want the static kind
return filterByClass(results, "html-widget-output", false);
};
});
window.HTMLWidgets.widgets.push(staticBinding);
if (shinyMode) {
// Shiny is running. Register the definition with an output binding.
// The definition itself will not be the output binding, instead
// we will make an output binding object that delegates to the
// definition. This is because we foolishly used the same method
// name (renderValue) for htmlwidgets definition and Shiny bindings
// but they actually have quite different semantics (the Shiny
// bindings receive data that includes lots of metadata that it
// strips off before calling htmlwidgets renderValue). We can't
// just ignore the difference because in some widgets it's helpful
// to call this.renderValue() from inside of resize(), and if
// we're not delegating, then that call will go to the Shiny
// version instead of the htmlwidgets version.
// Merge defaults with definition, without mutating either.
var bindingDef = extend({}, defaults, definition);
// This object will be our actual Shiny binding.
var shinyBinding = new Shiny.OutputBinding();
// With a few exceptions, we'll want to simply use the bindingDef's
// version of methods if they are available, otherwise fall back to
// Shiny's defaults. NOTE: If Shiny's output bindings gain additional
// methods in the future, and we want them to be overrideable by
// HTMLWidget binding definitions, then we'll need to add them to this
// list.
delegateMethod(shinyBinding, bindingDef, "getId");
delegateMethod(shinyBinding, bindingDef, "onValueChange");
delegateMethod(shinyBinding, bindingDef, "onValueError");
delegateMethod(shinyBinding, bindingDef, "renderError");
delegateMethod(shinyBinding, bindingDef, "clearError");
delegateMethod(shinyBinding, bindingDef, "showProgress");
// The find, renderValue, and resize are handled differently, because we
// want to actually decorate the behavior of the bindingDef methods.
shinyBinding.find = function(scope) {
var results = bindingDef.find(scope);
// Only return elements that are Shiny outputs, not static ones
var dynamicResults = results.filter(".html-widget-output");
// It's possible that whatever caused Shiny to think there might be
// new dynamic outputs, also caused there to be new static outputs.
// Since there might be lots of different htmlwidgets bindings, we
// schedule execution for later--no need to staticRender multiple
// times.
if (results.length !== dynamicResults.length)
scheduleStaticRender();
return dynamicResults;
};
// Wrap renderValue to handle initialization, which unfortunately isn't
// supported natively by Shiny at the time of this writing.
shinyBinding.renderValue = function(el, data) {
Shiny.renderDependencies(data.deps);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var i = 0; data.evals && i < data.evals.length; i++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
}
if (!bindingDef.renderOnNullValue) {
if (data.x === null) {
el.style.visibility = "hidden";
return;
} else {
el.style.visibility = "inherit";
}
}
if (!elementData(el, "initialized")) {
initSizing(el);
elementData(el, "initialized", true);
if (bindingDef.initialize) {
var result = bindingDef.initialize(el, el.offsetWidth,
el.offsetHeight);
elementData(el, "init_result", result);
}
}
bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
};
// Only override resize if bindingDef implements it
if (bindingDef.resize) {
shinyBinding.resize = function(el, width, height) {
// Shiny can call resize before initialize/renderValue have been
// called, which doesn't make sense for widgets.
if (elementData(el, "initialized")) {
bindingDef.resize(el, width, height, elementData(el, "init_result"));
}
};
}
Shiny.outputBindings.register(shinyBinding, bindingDef.name);
}
};
var scheduleStaticRenderTimerId = null;
function scheduleStaticRender() {
if (!scheduleStaticRenderTimerId) {
scheduleStaticRenderTimerId = setTimeout(function() {
scheduleStaticRenderTimerId = null;
window.HTMLWidgets.staticRender();
}, 1);
}
}
// Render static widgets after the document finishes loading
// Statically render all elements that are of this widget's class
window.HTMLWidgets.staticRender = function() {
var bindings = window.HTMLWidgets.widgets || [];
forEach(bindings, function(binding) {
var matches = binding.find(document.documentElement);
forEach(matches, function(el) {
var sizeObj = initSizing(el, binding);
if (hasClass(el, "html-widget-static-bound"))
return;
el.className = el.className + " html-widget-static-bound";
var initResult;
if (binding.initialize) {
initResult = binding.initialize(el,
sizeObj ? sizeObj.getWidth() : el.offsetWidth,
sizeObj ? sizeObj.getHeight() : el.offsetHeight
);
elementData(el, "init_result", initResult);
}
if (binding.resize) {
var lastSize = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
var resizeHandler = function(e) {
var size = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
if (size.w === 0 && size.h === 0)
return;
if (size.w === lastSize.w && size.h === lastSize.h)
return;
lastSize = size;
binding.resize(el, size.w, size.h, initResult);
};
on(window, "resize", resizeHandler);
// This is needed for cases where we're running in a Shiny
// app, but the widget itself is not a Shiny output, but
// rather a simple static widget. One example of this is
// an rmarkdown document that has runtime:shiny and widget
// that isn't in a render function. Shiny only knows to
// call resize handlers for Shiny outputs, not for static
// widgets, so we do it ourselves.
if (window.jQuery) {
window.jQuery(document).on(
"shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
resizeHandler
);
window.jQuery(document).on(
"hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
resizeHandler
);
}
// This is needed for the specific case of ioslides, which
// flips slides between display:none and display:block.
// Ideally we would not have to have ioslide-specific code
// here, but rather have ioslides raise a generic event,
// but the rmarkdown package just went to CRAN so the
// window to getting that fixed may be long.
if (window.addEventListener) {
// It's OK to limit this to window.addEventListener
// browsers because ioslides itself only supports
// such browsers.
on(document, "slideenter", resizeHandler);
on(document, "slideleave", resizeHandler);
}
}
var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
if (scriptData) {
var data = JSON.parse(scriptData.textContent || scriptData.text);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var k = 0; data.evals && k < data.evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
}
binding.renderValue(el, data.x, initResult);
evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
}
});
});
invokePostRenderHandlers();
}
function has_jQuery3() {
if (!window.jQuery) {
return false;
}
var $version = window.jQuery.fn.jquery;
var $major_version = parseInt($version.split(".")[0]);
return $major_version >= 3;
}
/*
/ Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
/ on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
/ really means $(setTimeout(fn)).
/ https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
/
/ Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
/ one tick later than it did before, which means staticRender() is
/ called renderValue() earlier than (advanced) widget authors might be expecting.
/ https://github.com/rstudio/shiny/issues/2630
/
/ For a concrete example, leaflet has some methods (e.g., updateBounds)
/ which reference Shiny methods registered in initShiny (e.g., setInputValue).
/ Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
/ delay execution of those methods (until Shiny methods are ready)
/ https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
/
/ Ideally widget authors wouldn't need to use this setTimeout() hack that
/ leaflet uses to call Shiny methods on a staticRender(). In the long run,
/ the logic initShiny should be broken up so that method registration happens
/ right away, but binding happens later.
*/
function maybeStaticRenderLater() {
if (shinyMode && has_jQuery3()) {
window.jQuery(window.HTMLWidgets.staticRender);
} else {
window.HTMLWidgets.staticRender();
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
maybeStaticRenderLater();
}, false);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
maybeStaticRenderLater();
}
});
}
window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
// If no key, default to the first item
if (typeof(key) === "undefined")
key = 1;
var link = document.getElementById(depname + "-" + key + "-attachment");
if (!link) {
throw new Error("Attachment " + depname + "/" + key + " not found in document");
}
return link.getAttribute("href");
};
window.HTMLWidgets.dataframeToD3 = function(df) {
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
window.HTMLWidgets.transposeArray2D = function(array) {
if (array.length === 0) return array;
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
};
// Split value at splitChar, but allow splitChar to be escaped
// using escapeChar. Any other characters escaped by escapeChar
// will be included as usual (including escapeChar itself).
function splitWithEscape(value, splitChar, escapeChar) {
var results = [];
var escapeMode = false;
var currentResult = "";
for (var pos = 0; pos < value.length; pos++) {
if (!escapeMode) {
if (value[pos] === splitChar) {
results.push(currentResult);
currentResult = "";
} else if (value[pos] === escapeChar) {
escapeMode = true;
} else {
currentResult += value[pos];
}
} else {
currentResult += value[pos];
escapeMode = false;
}
}
if (currentResult !== "") {
results.push(currentResult);
}
return results;
}
// Function authored by Yihui/JJ Allaire
window.HTMLWidgets.evaluateStringMember = function(o, member) {
var parts = splitWithEscape(member, '.', '\\');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// part may be a character or 'numeric' member name
if (o !== null && typeof o === "object" && part in o) {
if (i == (l - 1)) { // if we are at the end of the line then evalulate
if (typeof o[part] === "string")
o[part] = tryEval(o[part]);
} else { // otherwise continue to next embedded object
o = o[part];
}
}
}
};
// Retrieve the HTMLWidget instance (i.e. the return value of an
// HTMLWidget binding's initialize() or factory() function)
// associated with an element, or null if none.
window.HTMLWidgets.getInstance = function(el) {
return elementData(el, "init_result");
};
// Finds the first element in the scope that matches the selector,
// and returns the HTMLWidget instance (i.e. the return value of
// an HTMLWidget binding's initialize() or factory() function)
// associated with that element, if any. If no element matches the
// selector, or the first matching element has no HTMLWidget
// instance associated with it, then null is returned.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.find = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var el = scope.querySelector(selector);
if (el === null) {
return null;
} else {
return window.HTMLWidgets.getInstance(el);
}
};
// Finds all elements in the scope that match the selector, and
// returns the HTMLWidget instances (i.e. the return values of
// an HTMLWidget binding's initialize() or factory() function)
// associated with the elements, in an array. If elements that
// match the selector don't have an associated HTMLWidget
// instance, the returned array will contain nulls.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.findAll = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var nodes = scope.querySelectorAll(selector);
var results = [];
for (var i = 0; i < nodes.length; i++) {
results.push(window.HTMLWidgets.getInstance(nodes[i]));
}
return results;
};
var postRenderHandlers = [];
function invokePostRenderHandlers() {
while (postRenderHandlers.length) {
var handler = postRenderHandlers.shift();
if (handler) {
handler();
}
}
}
// Register the given callback function to be invoked after the
// next time static widgets are rendered.
window.HTMLWidgets.addPostRenderHandler = function(callback) {
postRenderHandlers.push(callback);
};
// Takes a new-style instance-bound definition, and returns an
// old-style class-bound definition. This saves us from having
// to rewrite all the logic in this file to accomodate both
// types of definitions.
function createLegacyDefinitionAdapter(defn) {
var result = {
name: defn.name,
type: defn.type,
initialize: function(el, width, height) {
return defn.factory(el, width, height);
},
renderValue: function(el, x, instance) {
return instance.renderValue(x);
},
resize: function(el, width, height, instance) {
return instance.resize(width, height);
}
};
if (defn.find)
result.find = defn.find;
if (defn.renderError)
result.renderError = defn.renderError;
if (defn.clearError)
result.clearError = defn.clearError;
return result;
}
})();

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);
}
});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,903 +0,0 @@
(function() {
// If window.HTMLWidgets is already defined, then use it; otherwise create a
// new object. This allows preceding code to set options that affect the
// initialization process (though none currently exist).
window.HTMLWidgets = window.HTMLWidgets || {};
// See if we're running in a viewer pane. If not, we're in a web browser.
var viewerMode = window.HTMLWidgets.viewerMode =
/\bviewer_pane=1\b/.test(window.location);
// See if we're running in Shiny mode. If not, it's a static document.
// Note that static widgets can appear in both Shiny and static modes, but
// obviously, Shiny widgets can only appear in Shiny apps/documents.
var shinyMode = window.HTMLWidgets.shinyMode =
typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
// We can't count on jQuery being available, so we implement our own
// version if necessary.
function querySelectorAll(scope, selector) {
if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
return scope.find(selector);
}
if (scope.querySelectorAll) {
return scope.querySelectorAll(selector);
}
}
function asArray(value) {
if (value === null)
return [];
if ($.isArray(value))
return value;
return [value];
}
// Implement jQuery's extend
function extend(target /*, ... */) {
if (arguments.length == 1) {
return target;
}
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
// IE8 doesn't support Array.forEach.
function forEach(values, callback, thisArg) {
if (values.forEach) {
values.forEach(callback, thisArg);
} else {
for (var i = 0; i < values.length; i++) {
callback.call(thisArg, values[i], i, values);
}
}
}
// Replaces the specified method with the return value of funcSource.
//
// Note that funcSource should not BE the new method, it should be a function
// that RETURNS the new method. funcSource receives a single argument that is
// the overridden method, it can be called from the new method. The overridden
// method can be called like a regular function, it has the target permanently
// bound to it so "this" will work correctly.
function overrideMethod(target, methodName, funcSource) {
var superFunc = target[methodName] || function() {};
var superFuncBound = function() {
return superFunc.apply(target, arguments);
};
target[methodName] = funcSource(superFuncBound);
}
// Add a method to delegator that, when invoked, calls
// delegatee.methodName. If there is no such method on
// the delegatee, but there was one on delegator before
// delegateMethod was called, then the original version
// is invoked instead.
// For example:
//
// var a = {
// method1: function() { console.log('a1'); }
// method2: function() { console.log('a2'); }
// };
// var b = {
// method1: function() { console.log('b1'); }
// };
// delegateMethod(a, b, "method1");
// delegateMethod(a, b, "method2");
// a.method1();
// a.method2();
//
// The output would be "b1", "a2".
function delegateMethod(delegator, delegatee, methodName) {
var inherited = delegator[methodName];
delegator[methodName] = function() {
var target = delegatee;
var method = delegatee[methodName];
// The method doesn't exist on the delegatee. Instead,
// call the method on the delegator, if it exists.
if (!method) {
target = delegator;
method = inherited;
}
if (method) {
return method.apply(target, arguments);
}
};
}
// Implement a vague facsimilie of jQuery's data method
function elementData(el, name, value) {
if (arguments.length == 2) {
return el["htmlwidget_data_" + name];
} else if (arguments.length == 3) {
el["htmlwidget_data_" + name] = value;
return el;
} else {
throw new Error("Wrong number of arguments for elementData: " +
arguments.length);
}
}
// http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function hasClass(el, className) {
var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
return re.test(el.className);
}
// elements - array (or array-like object) of HTML elements
// className - class name to test for
// include - if true, only return elements with given className;
// if false, only return elements *without* given className
function filterByClass(elements, className, include) {
var results = [];
for (var i = 0; i < elements.length; i++) {
if (hasClass(elements[i], className) == include)
results.push(elements[i]);
}
return results;
}
function on(obj, eventName, func) {
if (obj.addEventListener) {
obj.addEventListener(eventName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(eventName, func);
}
}
function off(obj, eventName, func) {
if (obj.removeEventListener)
obj.removeEventListener(eventName, func, false);
else if (obj.detachEvent) {
obj.detachEvent(eventName, func);
}
}
// Translate array of values to top/right/bottom/left, as usual with
// the "padding" CSS property
// https://developer.mozilla.org/en-US/docs/Web/CSS/padding
function unpackPadding(value) {
if (typeof(value) === "number")
value = [value];
if (value.length === 1) {
return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
}
if (value.length === 2) {
return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
}
if (value.length === 3) {
return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
}
if (value.length === 4) {
return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
}
}
// Convert an unpacked padding object to a CSS value
function paddingToCss(paddingObj) {
return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
}
// Makes a number suitable for CSS
function px(x) {
if (typeof(x) === "number")
return x + "px";
else
return x;
}
// Retrieves runtime widget sizing information for an element.
// The return value is either null, or an object with fill, padding,
// defaultWidth, defaultHeight fields.
function sizingPolicy(el) {
var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
if (!sizingEl)
return null;
var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
if (viewerMode) {
return sp.viewer;
} else {
return sp.browser;
}
}
// @param tasks Array of strings (or falsy value, in which case no-op).
// Each element must be a valid JavaScript expression that yields a
// function. Or, can be an array of objects with "code" and "data"
// properties; in this case, the "code" property should be a string
// of JS that's an expr that yields a function, and "data" should be
// an object that will be added as an additional argument when that
// function is called.
// @param target The object that will be "this" for each function
// execution.
// @param args Array of arguments to be passed to the functions. (The
// same arguments will be passed to all functions.)
function evalAndRun(tasks, target, args) {
if (tasks) {
forEach(tasks, function(task) {
var theseArgs = args;
if (typeof(task) === "object") {
theseArgs = theseArgs.concat([task.data]);
task = task.code;
}
var taskFunc = tryEval(task);
if (typeof(taskFunc) !== "function") {
throw new Error("Task must be a function! Source:\n" + task);
}
taskFunc.apply(target, theseArgs);
});
}
}
// Attempt eval() both with and without enclosing in parentheses.
// Note that enclosing coerces a function declaration into
// an expression that eval() can parse
// (otherwise, a SyntaxError is thrown)
function tryEval(code) {
var result = null;
try {
result = eval(code);
} catch(error) {
if (!error instanceof SyntaxError) {
throw error;
}
try {
result = eval("(" + code + ")");
} catch(e) {
if (e instanceof SyntaxError) {
throw error;
} else {
throw e;
}
}
}
return result;
}
function initSizing(el) {
var sizing = sizingPolicy(el);
if (!sizing)
return;
var cel = document.getElementById("htmlwidget_container");
if (!cel)
return;
if (typeof(sizing.padding) !== "undefined") {
document.body.style.margin = "0";
document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
}
if (sizing.fill) {
document.body.style.overflow = "hidden";
document.body.style.width = "100%";
document.body.style.height = "100%";
document.documentElement.style.width = "100%";
document.documentElement.style.height = "100%";
if (cel) {
cel.style.position = "absolute";
var pad = unpackPadding(sizing.padding);
cel.style.top = pad.top + "px";
cel.style.right = pad.right + "px";
cel.style.bottom = pad.bottom + "px";
cel.style.left = pad.left + "px";
el.style.width = "100%";
el.style.height = "100%";
}
return {
getWidth: function() { return cel.offsetWidth; },
getHeight: function() { return cel.offsetHeight; }
};
} else {
el.style.width = px(sizing.width);
el.style.height = px(sizing.height);
return {
getWidth: function() { return el.offsetWidth; },
getHeight: function() { return el.offsetHeight; }
};
}
}
// Default implementations for methods
var defaults = {
find: function(scope) {
return querySelectorAll(scope, "." + this.name);
},
renderError: function(el, err) {
var $el = $(el);
this.clearError(el);
// Add all these error classes, as Shiny does
var errClass = "shiny-output-error";
if (err.type !== null) {
// use the classes of the error condition as CSS class names
errClass = errClass + " " + $.map(asArray(err.type), function(type) {
return errClass + "-" + type;
}).join(" ");
}
errClass = errClass + " htmlwidgets-error";
// Is el inline or block? If inline or inline-block, just display:none it
// and add an inline error.
var display = $el.css("display");
$el.data("restore-display-mode", display);
if (display === "inline" || display === "inline-block") {
$el.hide();
if (err.message !== "") {
var errorSpan = $("<span>").addClass(errClass);
errorSpan.text(err.message);
$el.after(errorSpan);
}
} else if (display === "block") {
// If block, add an error just after the el, set visibility:none on the
// el, and position the error to be on top of the el.
// Mark it with a unique ID and CSS class so we can remove it later.
$el.css("visibility", "hidden");
if (err.message !== "") {
var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
// setting width can push out the page size, forcing otherwise
// unnecessary scrollbars to appear and making it impossible for
// the element to shrink; so use max-width instead
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
errorDiv.text(err.message);
$el.after(errorDiv);
// Really dumb way to keep the size/position of the error in sync with
// the parent element as the window is resized or whatever.
var intId = setInterval(function() {
if (!errorDiv[0].parentElement) {
clearInterval(intId);
return;
}
errorDiv
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
}, 500);
}
}
},
clearError: function(el) {
var $el = $(el);
var display = $el.data("restore-display-mode");
$el.data("restore-display-mode", null);
if (display === "inline" || display === "inline-block") {
if (display)
$el.css("display", display);
$(el.nextSibling).filter(".htmlwidgets-error").remove();
} else if (display === "block"){
$el.css("visibility", "inherit");
$(el.nextSibling).filter(".htmlwidgets-error").remove();
}
},
sizing: {}
};
// Called by widget bindings to register a new type of widget. The definition
// object can contain the following properties:
// - name (required) - A string indicating the binding name, which will be
// used by default as the CSS classname to look for.
// - initialize (optional) - A function(el) that will be called once per
// widget element; if a value is returned, it will be passed as the third
// value to renderValue.
// - renderValue (required) - A function(el, data, initValue) that will be
// called with data. Static contexts will cause this to be called once per
// element; Shiny apps will cause this to be called multiple times per
// element, as the data changes.
window.HTMLWidgets.widget = function(definition) {
if (!definition.name) {
throw new Error("Widget must have a name");
}
if (!definition.type) {
throw new Error("Widget must have a type");
}
// Currently we only support output widgets
if (definition.type !== "output") {
throw new Error("Unrecognized widget type '" + definition.type + "'");
}
// TODO: Verify that .name is a valid CSS classname
// Support new-style instance-bound definitions. Old-style class-bound
// definitions have one widget "object" per widget per type/class of
// widget; the renderValue and resize methods on such widget objects
// take el and instance arguments, because the widget object can't
// store them. New-style instance-bound definitions have one widget
// object per widget instance; the definition that's passed in doesn't
// provide renderValue or resize methods at all, just the single method
// factory(el, width, height)
// which returns an object that has renderValue(x) and resize(w, h).
// This enables a far more natural programming style for the widget
// author, who can store per-instance state using either OO-style
// instance fields or functional-style closure variables (I guess this
// is in contrast to what can only be called C-style pseudo-OO which is
// what we required before).
if (definition.factory) {
definition = createLegacyDefinitionAdapter(definition);
}
if (!definition.renderValue) {
throw new Error("Widget must have a renderValue function");
}
// For static rendering (non-Shiny), use a simple widget registration
// scheme. We also use this scheme for Shiny apps/documents that also
// contain static widgets.
window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
// Merge defaults into the definition; don't mutate the original definition.
var staticBinding = extend({}, defaults, definition);
overrideMethod(staticBinding, "find", function(superfunc) {
return function(scope) {
var results = superfunc(scope);
// Filter out Shiny outputs, we only want the static kind
return filterByClass(results, "html-widget-output", false);
};
});
window.HTMLWidgets.widgets.push(staticBinding);
if (shinyMode) {
// Shiny is running. Register the definition with an output binding.
// The definition itself will not be the output binding, instead
// we will make an output binding object that delegates to the
// definition. This is because we foolishly used the same method
// name (renderValue) for htmlwidgets definition and Shiny bindings
// but they actually have quite different semantics (the Shiny
// bindings receive data that includes lots of metadata that it
// strips off before calling htmlwidgets renderValue). We can't
// just ignore the difference because in some widgets it's helpful
// to call this.renderValue() from inside of resize(), and if
// we're not delegating, then that call will go to the Shiny
// version instead of the htmlwidgets version.
// Merge defaults with definition, without mutating either.
var bindingDef = extend({}, defaults, definition);
// This object will be our actual Shiny binding.
var shinyBinding = new Shiny.OutputBinding();
// With a few exceptions, we'll want to simply use the bindingDef's
// version of methods if they are available, otherwise fall back to
// Shiny's defaults. NOTE: If Shiny's output bindings gain additional
// methods in the future, and we want them to be overrideable by
// HTMLWidget binding definitions, then we'll need to add them to this
// list.
delegateMethod(shinyBinding, bindingDef, "getId");
delegateMethod(shinyBinding, bindingDef, "onValueChange");
delegateMethod(shinyBinding, bindingDef, "onValueError");
delegateMethod(shinyBinding, bindingDef, "renderError");
delegateMethod(shinyBinding, bindingDef, "clearError");
delegateMethod(shinyBinding, bindingDef, "showProgress");
// The find, renderValue, and resize are handled differently, because we
// want to actually decorate the behavior of the bindingDef methods.
shinyBinding.find = function(scope) {
var results = bindingDef.find(scope);
// Only return elements that are Shiny outputs, not static ones
var dynamicResults = results.filter(".html-widget-output");
// It's possible that whatever caused Shiny to think there might be
// new dynamic outputs, also caused there to be new static outputs.
// Since there might be lots of different htmlwidgets bindings, we
// schedule execution for later--no need to staticRender multiple
// times.
if (results.length !== dynamicResults.length)
scheduleStaticRender();
return dynamicResults;
};
// Wrap renderValue to handle initialization, which unfortunately isn't
// supported natively by Shiny at the time of this writing.
shinyBinding.renderValue = function(el, data) {
Shiny.renderDependencies(data.deps);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var i = 0; data.evals && i < data.evals.length; i++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
}
if (!bindingDef.renderOnNullValue) {
if (data.x === null) {
el.style.visibility = "hidden";
return;
} else {
el.style.visibility = "inherit";
}
}
if (!elementData(el, "initialized")) {
initSizing(el);
elementData(el, "initialized", true);
if (bindingDef.initialize) {
var result = bindingDef.initialize(el, el.offsetWidth,
el.offsetHeight);
elementData(el, "init_result", result);
}
}
bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
};
// Only override resize if bindingDef implements it
if (bindingDef.resize) {
shinyBinding.resize = function(el, width, height) {
// Shiny can call resize before initialize/renderValue have been
// called, which doesn't make sense for widgets.
if (elementData(el, "initialized")) {
bindingDef.resize(el, width, height, elementData(el, "init_result"));
}
};
}
Shiny.outputBindings.register(shinyBinding, bindingDef.name);
}
};
var scheduleStaticRenderTimerId = null;
function scheduleStaticRender() {
if (!scheduleStaticRenderTimerId) {
scheduleStaticRenderTimerId = setTimeout(function() {
scheduleStaticRenderTimerId = null;
window.HTMLWidgets.staticRender();
}, 1);
}
}
// Render static widgets after the document finishes loading
// Statically render all elements that are of this widget's class
window.HTMLWidgets.staticRender = function() {
var bindings = window.HTMLWidgets.widgets || [];
forEach(bindings, function(binding) {
var matches = binding.find(document.documentElement);
forEach(matches, function(el) {
var sizeObj = initSizing(el, binding);
if (hasClass(el, "html-widget-static-bound"))
return;
el.className = el.className + " html-widget-static-bound";
var initResult;
if (binding.initialize) {
initResult = binding.initialize(el,
sizeObj ? sizeObj.getWidth() : el.offsetWidth,
sizeObj ? sizeObj.getHeight() : el.offsetHeight
);
elementData(el, "init_result", initResult);
}
if (binding.resize) {
var lastSize = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
var resizeHandler = function(e) {
var size = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
if (size.w === 0 && size.h === 0)
return;
if (size.w === lastSize.w && size.h === lastSize.h)
return;
lastSize = size;
binding.resize(el, size.w, size.h, initResult);
};
on(window, "resize", resizeHandler);
// This is needed for cases where we're running in a Shiny
// app, but the widget itself is not a Shiny output, but
// rather a simple static widget. One example of this is
// an rmarkdown document that has runtime:shiny and widget
// that isn't in a render function. Shiny only knows to
// call resize handlers for Shiny outputs, not for static
// widgets, so we do it ourselves.
if (window.jQuery) {
window.jQuery(document).on(
"shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
resizeHandler
);
window.jQuery(document).on(
"hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
resizeHandler
);
}
// This is needed for the specific case of ioslides, which
// flips slides between display:none and display:block.
// Ideally we would not have to have ioslide-specific code
// here, but rather have ioslides raise a generic event,
// but the rmarkdown package just went to CRAN so the
// window to getting that fixed may be long.
if (window.addEventListener) {
// It's OK to limit this to window.addEventListener
// browsers because ioslides itself only supports
// such browsers.
on(document, "slideenter", resizeHandler);
on(document, "slideleave", resizeHandler);
}
}
var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
if (scriptData) {
var data = JSON.parse(scriptData.textContent || scriptData.text);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var k = 0; data.evals && k < data.evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
}
binding.renderValue(el, data.x, initResult);
evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
}
});
});
invokePostRenderHandlers();
}
function has_jQuery3() {
if (!window.jQuery) {
return false;
}
var $version = window.jQuery.fn.jquery;
var $major_version = parseInt($version.split(".")[0]);
return $major_version >= 3;
}
/*
/ Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
/ on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
/ really means $(setTimeout(fn)).
/ https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
/
/ Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
/ one tick later than it did before, which means staticRender() is
/ called renderValue() earlier than (advanced) widget authors might be expecting.
/ https://github.com/rstudio/shiny/issues/2630
/
/ For a concrete example, leaflet has some methods (e.g., updateBounds)
/ which reference Shiny methods registered in initShiny (e.g., setInputValue).
/ Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
/ delay execution of those methods (until Shiny methods are ready)
/ https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
/
/ Ideally widget authors wouldn't need to use this setTimeout() hack that
/ leaflet uses to call Shiny methods on a staticRender(). In the long run,
/ the logic initShiny should be broken up so that method registration happens
/ right away, but binding happens later.
*/
function maybeStaticRenderLater() {
if (shinyMode && has_jQuery3()) {
window.jQuery(window.HTMLWidgets.staticRender);
} else {
window.HTMLWidgets.staticRender();
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
maybeStaticRenderLater();
}, false);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
maybeStaticRenderLater();
}
});
}
window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
// If no key, default to the first item
if (typeof(key) === "undefined")
key = 1;
var link = document.getElementById(depname + "-" + key + "-attachment");
if (!link) {
throw new Error("Attachment " + depname + "/" + key + " not found in document");
}
return link.getAttribute("href");
};
window.HTMLWidgets.dataframeToD3 = function(df) {
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
window.HTMLWidgets.transposeArray2D = function(array) {
if (array.length === 0) return array;
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
};
// Split value at splitChar, but allow splitChar to be escaped
// using escapeChar. Any other characters escaped by escapeChar
// will be included as usual (including escapeChar itself).
function splitWithEscape(value, splitChar, escapeChar) {
var results = [];
var escapeMode = false;
var currentResult = "";
for (var pos = 0; pos < value.length; pos++) {
if (!escapeMode) {
if (value[pos] === splitChar) {
results.push(currentResult);
currentResult = "";
} else if (value[pos] === escapeChar) {
escapeMode = true;
} else {
currentResult += value[pos];
}
} else {
currentResult += value[pos];
escapeMode = false;
}
}
if (currentResult !== "") {
results.push(currentResult);
}
return results;
}
// Function authored by Yihui/JJ Allaire
window.HTMLWidgets.evaluateStringMember = function(o, member) {
var parts = splitWithEscape(member, '.', '\\');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// part may be a character or 'numeric' member name
if (o !== null && typeof o === "object" && part in o) {
if (i == (l - 1)) { // if we are at the end of the line then evalulate
if (typeof o[part] === "string")
o[part] = tryEval(o[part]);
} else { // otherwise continue to next embedded object
o = o[part];
}
}
}
};
// Retrieve the HTMLWidget instance (i.e. the return value of an
// HTMLWidget binding's initialize() or factory() function)
// associated with an element, or null if none.
window.HTMLWidgets.getInstance = function(el) {
return elementData(el, "init_result");
};
// Finds the first element in the scope that matches the selector,
// and returns the HTMLWidget instance (i.e. the return value of
// an HTMLWidget binding's initialize() or factory() function)
// associated with that element, if any. If no element matches the
// selector, or the first matching element has no HTMLWidget
// instance associated with it, then null is returned.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.find = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var el = scope.querySelector(selector);
if (el === null) {
return null;
} else {
return window.HTMLWidgets.getInstance(el);
}
};
// Finds all elements in the scope that match the selector, and
// returns the HTMLWidget instances (i.e. the return values of
// an HTMLWidget binding's initialize() or factory() function)
// associated with the elements, in an array. If elements that
// match the selector don't have an associated HTMLWidget
// instance, the returned array will contain nulls.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.findAll = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var nodes = scope.querySelectorAll(selector);
var results = [];
for (var i = 0; i < nodes.length; i++) {
results.push(window.HTMLWidgets.getInstance(nodes[i]));
}
return results;
};
var postRenderHandlers = [];
function invokePostRenderHandlers() {
while (postRenderHandlers.length) {
var handler = postRenderHandlers.shift();
if (handler) {
handler();
}
}
}
// Register the given callback function to be invoked after the
// next time static widgets are rendered.
window.HTMLWidgets.addPostRenderHandler = function(callback) {
postRenderHandlers.push(callback);
};
// Takes a new-style instance-bound definition, and returns an
// old-style class-bound definition. This saves us from having
// to rewrite all the logic in this file to accomodate both
// types of definitions.
function createLegacyDefinitionAdapter(defn) {
var result = {
name: defn.name,
type: defn.type,
initialize: function(el, width, height) {
return defn.factory(el, width, height);
},
renderValue: function(el, x, instance) {
return instance.renderValue(x);
},
resize: function(el, width, height, instance) {
return instance.resize(width, height);
}
};
if (defn.find)
result.find = defn.find;
if (defn.renderError)
result.renderError = defn.renderError;
if (defn.clearError)
result.clearError = defn.clearError;
return result;
}
})();

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);
}
});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,903 +0,0 @@
(function() {
// If window.HTMLWidgets is already defined, then use it; otherwise create a
// new object. This allows preceding code to set options that affect the
// initialization process (though none currently exist).
window.HTMLWidgets = window.HTMLWidgets || {};
// See if we're running in a viewer pane. If not, we're in a web browser.
var viewerMode = window.HTMLWidgets.viewerMode =
/\bviewer_pane=1\b/.test(window.location);
// See if we're running in Shiny mode. If not, it's a static document.
// Note that static widgets can appear in both Shiny and static modes, but
// obviously, Shiny widgets can only appear in Shiny apps/documents.
var shinyMode = window.HTMLWidgets.shinyMode =
typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
// We can't count on jQuery being available, so we implement our own
// version if necessary.
function querySelectorAll(scope, selector) {
if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
return scope.find(selector);
}
if (scope.querySelectorAll) {
return scope.querySelectorAll(selector);
}
}
function asArray(value) {
if (value === null)
return [];
if ($.isArray(value))
return value;
return [value];
}
// Implement jQuery's extend
function extend(target /*, ... */) {
if (arguments.length == 1) {
return target;
}
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
// IE8 doesn't support Array.forEach.
function forEach(values, callback, thisArg) {
if (values.forEach) {
values.forEach(callback, thisArg);
} else {
for (var i = 0; i < values.length; i++) {
callback.call(thisArg, values[i], i, values);
}
}
}
// Replaces the specified method with the return value of funcSource.
//
// Note that funcSource should not BE the new method, it should be a function
// that RETURNS the new method. funcSource receives a single argument that is
// the overridden method, it can be called from the new method. The overridden
// method can be called like a regular function, it has the target permanently
// bound to it so "this" will work correctly.
function overrideMethod(target, methodName, funcSource) {
var superFunc = target[methodName] || function() {};
var superFuncBound = function() {
return superFunc.apply(target, arguments);
};
target[methodName] = funcSource(superFuncBound);
}
// Add a method to delegator that, when invoked, calls
// delegatee.methodName. If there is no such method on
// the delegatee, but there was one on delegator before
// delegateMethod was called, then the original version
// is invoked instead.
// For example:
//
// var a = {
// method1: function() { console.log('a1'); }
// method2: function() { console.log('a2'); }
// };
// var b = {
// method1: function() { console.log('b1'); }
// };
// delegateMethod(a, b, "method1");
// delegateMethod(a, b, "method2");
// a.method1();
// a.method2();
//
// The output would be "b1", "a2".
function delegateMethod(delegator, delegatee, methodName) {
var inherited = delegator[methodName];
delegator[methodName] = function() {
var target = delegatee;
var method = delegatee[methodName];
// The method doesn't exist on the delegatee. Instead,
// call the method on the delegator, if it exists.
if (!method) {
target = delegator;
method = inherited;
}
if (method) {
return method.apply(target, arguments);
}
};
}
// Implement a vague facsimilie of jQuery's data method
function elementData(el, name, value) {
if (arguments.length == 2) {
return el["htmlwidget_data_" + name];
} else if (arguments.length == 3) {
el["htmlwidget_data_" + name] = value;
return el;
} else {
throw new Error("Wrong number of arguments for elementData: " +
arguments.length);
}
}
// http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function hasClass(el, className) {
var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
return re.test(el.className);
}
// elements - array (or array-like object) of HTML elements
// className - class name to test for
// include - if true, only return elements with given className;
// if false, only return elements *without* given className
function filterByClass(elements, className, include) {
var results = [];
for (var i = 0; i < elements.length; i++) {
if (hasClass(elements[i], className) == include)
results.push(elements[i]);
}
return results;
}
function on(obj, eventName, func) {
if (obj.addEventListener) {
obj.addEventListener(eventName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(eventName, func);
}
}
function off(obj, eventName, func) {
if (obj.removeEventListener)
obj.removeEventListener(eventName, func, false);
else if (obj.detachEvent) {
obj.detachEvent(eventName, func);
}
}
// Translate array of values to top/right/bottom/left, as usual with
// the "padding" CSS property
// https://developer.mozilla.org/en-US/docs/Web/CSS/padding
function unpackPadding(value) {
if (typeof(value) === "number")
value = [value];
if (value.length === 1) {
return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
}
if (value.length === 2) {
return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
}
if (value.length === 3) {
return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
}
if (value.length === 4) {
return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
}
}
// Convert an unpacked padding object to a CSS value
function paddingToCss(paddingObj) {
return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
}
// Makes a number suitable for CSS
function px(x) {
if (typeof(x) === "number")
return x + "px";
else
return x;
}
// Retrieves runtime widget sizing information for an element.
// The return value is either null, or an object with fill, padding,
// defaultWidth, defaultHeight fields.
function sizingPolicy(el) {
var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
if (!sizingEl)
return null;
var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
if (viewerMode) {
return sp.viewer;
} else {
return sp.browser;
}
}
// @param tasks Array of strings (or falsy value, in which case no-op).
// Each element must be a valid JavaScript expression that yields a
// function. Or, can be an array of objects with "code" and "data"
// properties; in this case, the "code" property should be a string
// of JS that's an expr that yields a function, and "data" should be
// an object that will be added as an additional argument when that
// function is called.
// @param target The object that will be "this" for each function
// execution.
// @param args Array of arguments to be passed to the functions. (The
// same arguments will be passed to all functions.)
function evalAndRun(tasks, target, args) {
if (tasks) {
forEach(tasks, function(task) {
var theseArgs = args;
if (typeof(task) === "object") {
theseArgs = theseArgs.concat([task.data]);
task = task.code;
}
var taskFunc = tryEval(task);
if (typeof(taskFunc) !== "function") {
throw new Error("Task must be a function! Source:\n" + task);
}
taskFunc.apply(target, theseArgs);
});
}
}
// Attempt eval() both with and without enclosing in parentheses.
// Note that enclosing coerces a function declaration into
// an expression that eval() can parse
// (otherwise, a SyntaxError is thrown)
function tryEval(code) {
var result = null;
try {
result = eval(code);
} catch(error) {
if (!error instanceof SyntaxError) {
throw error;
}
try {
result = eval("(" + code + ")");
} catch(e) {
if (e instanceof SyntaxError) {
throw error;
} else {
throw e;
}
}
}
return result;
}
function initSizing(el) {
var sizing = sizingPolicy(el);
if (!sizing)
return;
var cel = document.getElementById("htmlwidget_container");
if (!cel)
return;
if (typeof(sizing.padding) !== "undefined") {
document.body.style.margin = "0";
document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
}
if (sizing.fill) {
document.body.style.overflow = "hidden";
document.body.style.width = "100%";
document.body.style.height = "100%";
document.documentElement.style.width = "100%";
document.documentElement.style.height = "100%";
if (cel) {
cel.style.position = "absolute";
var pad = unpackPadding(sizing.padding);
cel.style.top = pad.top + "px";
cel.style.right = pad.right + "px";
cel.style.bottom = pad.bottom + "px";
cel.style.left = pad.left + "px";
el.style.width = "100%";
el.style.height = "100%";
}
return {
getWidth: function() { return cel.offsetWidth; },
getHeight: function() { return cel.offsetHeight; }
};
} else {
el.style.width = px(sizing.width);
el.style.height = px(sizing.height);
return {
getWidth: function() { return el.offsetWidth; },
getHeight: function() { return el.offsetHeight; }
};
}
}
// Default implementations for methods
var defaults = {
find: function(scope) {
return querySelectorAll(scope, "." + this.name);
},
renderError: function(el, err) {
var $el = $(el);
this.clearError(el);
// Add all these error classes, as Shiny does
var errClass = "shiny-output-error";
if (err.type !== null) {
// use the classes of the error condition as CSS class names
errClass = errClass + " " + $.map(asArray(err.type), function(type) {
return errClass + "-" + type;
}).join(" ");
}
errClass = errClass + " htmlwidgets-error";
// Is el inline or block? If inline or inline-block, just display:none it
// and add an inline error.
var display = $el.css("display");
$el.data("restore-display-mode", display);
if (display === "inline" || display === "inline-block") {
$el.hide();
if (err.message !== "") {
var errorSpan = $("<span>").addClass(errClass);
errorSpan.text(err.message);
$el.after(errorSpan);
}
} else if (display === "block") {
// If block, add an error just after the el, set visibility:none on the
// el, and position the error to be on top of the el.
// Mark it with a unique ID and CSS class so we can remove it later.
$el.css("visibility", "hidden");
if (err.message !== "") {
var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
// setting width can push out the page size, forcing otherwise
// unnecessary scrollbars to appear and making it impossible for
// the element to shrink; so use max-width instead
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
errorDiv.text(err.message);
$el.after(errorDiv);
// Really dumb way to keep the size/position of the error in sync with
// the parent element as the window is resized or whatever.
var intId = setInterval(function() {
if (!errorDiv[0].parentElement) {
clearInterval(intId);
return;
}
errorDiv
.css("top", el.offsetTop)
.css("left", el.offsetLeft)
.css("maxWidth", el.offsetWidth)
.css("height", el.offsetHeight);
}, 500);
}
}
},
clearError: function(el) {
var $el = $(el);
var display = $el.data("restore-display-mode");
$el.data("restore-display-mode", null);
if (display === "inline" || display === "inline-block") {
if (display)
$el.css("display", display);
$(el.nextSibling).filter(".htmlwidgets-error").remove();
} else if (display === "block"){
$el.css("visibility", "inherit");
$(el.nextSibling).filter(".htmlwidgets-error").remove();
}
},
sizing: {}
};
// Called by widget bindings to register a new type of widget. The definition
// object can contain the following properties:
// - name (required) - A string indicating the binding name, which will be
// used by default as the CSS classname to look for.
// - initialize (optional) - A function(el) that will be called once per
// widget element; if a value is returned, it will be passed as the third
// value to renderValue.
// - renderValue (required) - A function(el, data, initValue) that will be
// called with data. Static contexts will cause this to be called once per
// element; Shiny apps will cause this to be called multiple times per
// element, as the data changes.
window.HTMLWidgets.widget = function(definition) {
if (!definition.name) {
throw new Error("Widget must have a name");
}
if (!definition.type) {
throw new Error("Widget must have a type");
}
// Currently we only support output widgets
if (definition.type !== "output") {
throw new Error("Unrecognized widget type '" + definition.type + "'");
}
// TODO: Verify that .name is a valid CSS classname
// Support new-style instance-bound definitions. Old-style class-bound
// definitions have one widget "object" per widget per type/class of
// widget; the renderValue and resize methods on such widget objects
// take el and instance arguments, because the widget object can't
// store them. New-style instance-bound definitions have one widget
// object per widget instance; the definition that's passed in doesn't
// provide renderValue or resize methods at all, just the single method
// factory(el, width, height)
// which returns an object that has renderValue(x) and resize(w, h).
// This enables a far more natural programming style for the widget
// author, who can store per-instance state using either OO-style
// instance fields or functional-style closure variables (I guess this
// is in contrast to what can only be called C-style pseudo-OO which is
// what we required before).
if (definition.factory) {
definition = createLegacyDefinitionAdapter(definition);
}
if (!definition.renderValue) {
throw new Error("Widget must have a renderValue function");
}
// For static rendering (non-Shiny), use a simple widget registration
// scheme. We also use this scheme for Shiny apps/documents that also
// contain static widgets.
window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
// Merge defaults into the definition; don't mutate the original definition.
var staticBinding = extend({}, defaults, definition);
overrideMethod(staticBinding, "find", function(superfunc) {
return function(scope) {
var results = superfunc(scope);
// Filter out Shiny outputs, we only want the static kind
return filterByClass(results, "html-widget-output", false);
};
});
window.HTMLWidgets.widgets.push(staticBinding);
if (shinyMode) {
// Shiny is running. Register the definition with an output binding.
// The definition itself will not be the output binding, instead
// we will make an output binding object that delegates to the
// definition. This is because we foolishly used the same method
// name (renderValue) for htmlwidgets definition and Shiny bindings
// but they actually have quite different semantics (the Shiny
// bindings receive data that includes lots of metadata that it
// strips off before calling htmlwidgets renderValue). We can't
// just ignore the difference because in some widgets it's helpful
// to call this.renderValue() from inside of resize(), and if
// we're not delegating, then that call will go to the Shiny
// version instead of the htmlwidgets version.
// Merge defaults with definition, without mutating either.
var bindingDef = extend({}, defaults, definition);
// This object will be our actual Shiny binding.
var shinyBinding = new Shiny.OutputBinding();
// With a few exceptions, we'll want to simply use the bindingDef's
// version of methods if they are available, otherwise fall back to
// Shiny's defaults. NOTE: If Shiny's output bindings gain additional
// methods in the future, and we want them to be overrideable by
// HTMLWidget binding definitions, then we'll need to add them to this
// list.
delegateMethod(shinyBinding, bindingDef, "getId");
delegateMethod(shinyBinding, bindingDef, "onValueChange");
delegateMethod(shinyBinding, bindingDef, "onValueError");
delegateMethod(shinyBinding, bindingDef, "renderError");
delegateMethod(shinyBinding, bindingDef, "clearError");
delegateMethod(shinyBinding, bindingDef, "showProgress");
// The find, renderValue, and resize are handled differently, because we
// want to actually decorate the behavior of the bindingDef methods.
shinyBinding.find = function(scope) {
var results = bindingDef.find(scope);
// Only return elements that are Shiny outputs, not static ones
var dynamicResults = results.filter(".html-widget-output");
// It's possible that whatever caused Shiny to think there might be
// new dynamic outputs, also caused there to be new static outputs.
// Since there might be lots of different htmlwidgets bindings, we
// schedule execution for later--no need to staticRender multiple
// times.
if (results.length !== dynamicResults.length)
scheduleStaticRender();
return dynamicResults;
};
// Wrap renderValue to handle initialization, which unfortunately isn't
// supported natively by Shiny at the time of this writing.
shinyBinding.renderValue = function(el, data) {
Shiny.renderDependencies(data.deps);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var i = 0; data.evals && i < data.evals.length; i++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
}
if (!bindingDef.renderOnNullValue) {
if (data.x === null) {
el.style.visibility = "hidden";
return;
} else {
el.style.visibility = "inherit";
}
}
if (!elementData(el, "initialized")) {
initSizing(el);
elementData(el, "initialized", true);
if (bindingDef.initialize) {
var result = bindingDef.initialize(el, el.offsetWidth,
el.offsetHeight);
elementData(el, "init_result", result);
}
}
bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
};
// Only override resize if bindingDef implements it
if (bindingDef.resize) {
shinyBinding.resize = function(el, width, height) {
// Shiny can call resize before initialize/renderValue have been
// called, which doesn't make sense for widgets.
if (elementData(el, "initialized")) {
bindingDef.resize(el, width, height, elementData(el, "init_result"));
}
};
}
Shiny.outputBindings.register(shinyBinding, bindingDef.name);
}
};
var scheduleStaticRenderTimerId = null;
function scheduleStaticRender() {
if (!scheduleStaticRenderTimerId) {
scheduleStaticRenderTimerId = setTimeout(function() {
scheduleStaticRenderTimerId = null;
window.HTMLWidgets.staticRender();
}, 1);
}
}
// Render static widgets after the document finishes loading
// Statically render all elements that are of this widget's class
window.HTMLWidgets.staticRender = function() {
var bindings = window.HTMLWidgets.widgets || [];
forEach(bindings, function(binding) {
var matches = binding.find(document.documentElement);
forEach(matches, function(el) {
var sizeObj = initSizing(el, binding);
if (hasClass(el, "html-widget-static-bound"))
return;
el.className = el.className + " html-widget-static-bound";
var initResult;
if (binding.initialize) {
initResult = binding.initialize(el,
sizeObj ? sizeObj.getWidth() : el.offsetWidth,
sizeObj ? sizeObj.getHeight() : el.offsetHeight
);
elementData(el, "init_result", initResult);
}
if (binding.resize) {
var lastSize = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
var resizeHandler = function(e) {
var size = {
w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
};
if (size.w === 0 && size.h === 0)
return;
if (size.w === lastSize.w && size.h === lastSize.h)
return;
lastSize = size;
binding.resize(el, size.w, size.h, initResult);
};
on(window, "resize", resizeHandler);
// This is needed for cases where we're running in a Shiny
// app, but the widget itself is not a Shiny output, but
// rather a simple static widget. One example of this is
// an rmarkdown document that has runtime:shiny and widget
// that isn't in a render function. Shiny only knows to
// call resize handlers for Shiny outputs, not for static
// widgets, so we do it ourselves.
if (window.jQuery) {
window.jQuery(document).on(
"shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
resizeHandler
);
window.jQuery(document).on(
"hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
resizeHandler
);
}
// This is needed for the specific case of ioslides, which
// flips slides between display:none and display:block.
// Ideally we would not have to have ioslide-specific code
// here, but rather have ioslides raise a generic event,
// but the rmarkdown package just went to CRAN so the
// window to getting that fixed may be long.
if (window.addEventListener) {
// It's OK to limit this to window.addEventListener
// browsers because ioslides itself only supports
// such browsers.
on(document, "slideenter", resizeHandler);
on(document, "slideleave", resizeHandler);
}
}
var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
if (scriptData) {
var data = JSON.parse(scriptData.textContent || scriptData.text);
// Resolve strings marked as javascript literals to objects
if (!(data.evals instanceof Array)) data.evals = [data.evals];
for (var k = 0; data.evals && k < data.evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
}
binding.renderValue(el, data.x, initResult);
evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
}
});
});
invokePostRenderHandlers();
}
function has_jQuery3() {
if (!window.jQuery) {
return false;
}
var $version = window.jQuery.fn.jquery;
var $major_version = parseInt($version.split(".")[0]);
return $major_version >= 3;
}
/*
/ Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
/ on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
/ really means $(setTimeout(fn)).
/ https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
/
/ Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
/ one tick later than it did before, which means staticRender() is
/ called renderValue() earlier than (advanced) widget authors might be expecting.
/ https://github.com/rstudio/shiny/issues/2630
/
/ For a concrete example, leaflet has some methods (e.g., updateBounds)
/ which reference Shiny methods registered in initShiny (e.g., setInputValue).
/ Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
/ delay execution of those methods (until Shiny methods are ready)
/ https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
/
/ Ideally widget authors wouldn't need to use this setTimeout() hack that
/ leaflet uses to call Shiny methods on a staticRender(). In the long run,
/ the logic initShiny should be broken up so that method registration happens
/ right away, but binding happens later.
*/
function maybeStaticRenderLater() {
if (shinyMode && has_jQuery3()) {
window.jQuery(window.HTMLWidgets.staticRender);
} else {
window.HTMLWidgets.staticRender();
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
maybeStaticRenderLater();
}, false);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
maybeStaticRenderLater();
}
});
}
window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
// If no key, default to the first item
if (typeof(key) === "undefined")
key = 1;
var link = document.getElementById(depname + "-" + key + "-attachment");
if (!link) {
throw new Error("Attachment " + depname + "/" + key + " not found in document");
}
return link.getAttribute("href");
};
window.HTMLWidgets.dataframeToD3 = function(df) {
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
window.HTMLWidgets.transposeArray2D = function(array) {
if (array.length === 0) return array;
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
};
// Split value at splitChar, but allow splitChar to be escaped
// using escapeChar. Any other characters escaped by escapeChar
// will be included as usual (including escapeChar itself).
function splitWithEscape(value, splitChar, escapeChar) {
var results = [];
var escapeMode = false;
var currentResult = "";
for (var pos = 0; pos < value.length; pos++) {
if (!escapeMode) {
if (value[pos] === splitChar) {
results.push(currentResult);
currentResult = "";
} else if (value[pos] === escapeChar) {
escapeMode = true;
} else {
currentResult += value[pos];
}
} else {
currentResult += value[pos];
escapeMode = false;
}
}
if (currentResult !== "") {
results.push(currentResult);
}
return results;
}
// Function authored by Yihui/JJ Allaire
window.HTMLWidgets.evaluateStringMember = function(o, member) {
var parts = splitWithEscape(member, '.', '\\');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// part may be a character or 'numeric' member name
if (o !== null && typeof o === "object" && part in o) {
if (i == (l - 1)) { // if we are at the end of the line then evalulate
if (typeof o[part] === "string")
o[part] = tryEval(o[part]);
} else { // otherwise continue to next embedded object
o = o[part];
}
}
}
};
// Retrieve the HTMLWidget instance (i.e. the return value of an
// HTMLWidget binding's initialize() or factory() function)
// associated with an element, or null if none.
window.HTMLWidgets.getInstance = function(el) {
return elementData(el, "init_result");
};
// Finds the first element in the scope that matches the selector,
// and returns the HTMLWidget instance (i.e. the return value of
// an HTMLWidget binding's initialize() or factory() function)
// associated with that element, if any. If no element matches the
// selector, or the first matching element has no HTMLWidget
// instance associated with it, then null is returned.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.find = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var el = scope.querySelector(selector);
if (el === null) {
return null;
} else {
return window.HTMLWidgets.getInstance(el);
}
};
// Finds all elements in the scope that match the selector, and
// returns the HTMLWidget instances (i.e. the return values of
// an HTMLWidget binding's initialize() or factory() function)
// associated with the elements, in an array. If elements that
// match the selector don't have an associated HTMLWidget
// instance, the returned array will contain nulls.
//
// The scope argument is optional, and defaults to window.document.
window.HTMLWidgets.findAll = function(scope, selector) {
if (arguments.length == 1) {
selector = scope;
scope = document;
}
var nodes = scope.querySelectorAll(selector);
var results = [];
for (var i = 0; i < nodes.length; i++) {
results.push(window.HTMLWidgets.getInstance(nodes[i]));
}
return results;
};
var postRenderHandlers = [];
function invokePostRenderHandlers() {
while (postRenderHandlers.length) {
var handler = postRenderHandlers.shift();
if (handler) {
handler();
}
}
}
// Register the given callback function to be invoked after the
// next time static widgets are rendered.
window.HTMLWidgets.addPostRenderHandler = function(callback) {
postRenderHandlers.push(callback);
};
// Takes a new-style instance-bound definition, and returns an
// old-style class-bound definition. This saves us from having
// to rewrite all the logic in this file to accomodate both
// types of definitions.
function createLegacyDefinitionAdapter(defn) {
var result = {
name: defn.name,
type: defn.type,
initialize: function(el, width, height) {
return defn.factory(el, width, height);
},
renderValue: function(el, x, instance) {
return instance.renderValue(x);
},
resize: function(el, width, height, instance) {
return instance.resize(width, height);
}
};
if (defn.find)
result.find = defn.find;
if (defn.renderError)
result.renderError = defn.renderError;
if (defn.clearError)
result.clearError = defn.clearError;
return result;
}
})();

View File

@ -1,246 +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>Authors • apexcharter</title>
<!-- jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<link href="css/theme.css" rel="stylesheet">
<!-- Font -->
<link href="css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- Particles -->
<script src="js/particles.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></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="Authors" />
<!-- 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-authors">
<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.3.990</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.3.990</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/labs.html">Labs: title, subtitle &amp; axis</a>
</li>
<li>
<a href="articles/lines.html">Options &amp; styles for lines</a>
</li>
<li>
<a href="articles/shiny-integration.html">Shiny integration</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>Authors</h1>
</div>
<ul class="list-unstyled">
<li>
<p><strong><a href='https://twitter.com/_pvictorr'><img src="https://pbs.twimg.com/profile_images/844237339404722177/E1U61aM8_normal.jpg"/> Victor Perrier</a></strong>. Author, maintainer.
</p>
</li>
<li>
<p><strong><a href='https://twitter.com/_mfaan'><img src="https://pbs.twimg.com/profile_images/912313931326218240/o1-wvA18_normal.jpg" /> Fanny Meyer</a></strong>. Author.
</p>
</li>
<li>
<p><strong>Juned Chhipa</strong>. Copyright holder.
<br /><small>apexcharts.js library</small></p>
</li>
<li>
<p><strong>Mike Bostock</strong>. Copyright holder.
<br /><small>d3.format library</small></p>
</li>
</ul>
</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.4.1.</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,216 +0,0 @@
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 100;
src: url('../fonts/montserrat-v14-latin-100.eot'); /* IE9 Compat Modes */
src: local('Montserrat Thin'), local('Montserrat-Thin'),
url('../fonts/montserrat-v14-latin-100.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-100.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-100.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-100.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-100.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 100;
src: url('../fonts/montserrat-v14-latin-100italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat Thin Italic'), local('Montserrat-ThinItalic'),
url('../fonts/montserrat-v14-latin-100italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-100italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-100italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-100italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-100italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 200;
src: url('../fonts/montserrat-v14-latin-200.eot'); /* IE9 Compat Modes */
src: local('Montserrat ExtraLight'), local('Montserrat-ExtraLight'),
url('../fonts/montserrat-v14-latin-200.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-200.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-200.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-200.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-200.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 200;
src: url('../fonts/montserrat-v14-latin-200italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat ExtraLight Italic'), local('Montserrat-ExtraLightItalic'),
url('../fonts/montserrat-v14-latin-200italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-200italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-200italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-200italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-200italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url('../fonts/montserrat-v14-latin-300.eot'); /* IE9 Compat Modes */
src: local('Montserrat Light'), local('Montserrat-Light'),
url('../fonts/montserrat-v14-latin-300.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-300.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-300.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-300.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-300.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 300;
src: url('../fonts/montserrat-v14-latin-300italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat Light Italic'), local('Montserrat-LightItalic'),
url('../fonts/montserrat-v14-latin-300italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-300italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-300italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-300italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-300italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url('../fonts/montserrat-v14-latin-regular.eot'); /* IE9 Compat Modes */
src: local('Montserrat Regular'), local('Montserrat-Regular'),
url('../fonts/montserrat-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-regular.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 400;
src: url('../fonts/montserrat-v14-latin-italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat Italic'), local('Montserrat-Italic'),
url('../fonts/montserrat-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url('../fonts/montserrat-v14-latin-500.eot'); /* IE9 Compat Modes */
src: local('Montserrat Medium'), local('Montserrat-Medium'),
url('../fonts/montserrat-v14-latin-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-500.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-500.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-500.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-500.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 500;
src: url('../fonts/montserrat-v14-latin-500italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat Medium Italic'), local('Montserrat-MediumItalic'),
url('../fonts/montserrat-v14-latin-500italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-500italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-500italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-500italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-500italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url('../fonts/montserrat-v14-latin-600.eot'); /* IE9 Compat Modes */
src: local('Montserrat SemiBold'), local('Montserrat-SemiBold'),
url('../fonts/montserrat-v14-latin-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-600.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-600.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-600.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-600.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 600;
src: url('../fonts/montserrat-v14-latin-600italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat SemiBold Italic'), local('Montserrat-SemiBoldItalic'),
url('../fonts/montserrat-v14-latin-600italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-600italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-600italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-600italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-600italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url('../fonts/montserrat-v14-latin-700.eot'); /* IE9 Compat Modes */
src: local('Montserrat Bold'), local('Montserrat-Bold'),
url('../fonts/montserrat-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-700.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-700.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 700;
src: url('../fonts/montserrat-v14-latin-700italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat Bold Italic'), local('Montserrat-BoldItalic'),
url('../fonts/montserrat-v14-latin-700italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-700italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-700italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-700italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-700italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 800;
src: url('../fonts/montserrat-v14-latin-800italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat ExtraBold Italic'), local('Montserrat-ExtraBoldItalic'),
url('../fonts/montserrat-v14-latin-800italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-800italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-800italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-800italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-800italic.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 800;
src: url('../fonts/montserrat-v14-latin-800.eot'); /* IE9 Compat Modes */
src: local('Montserrat ExtraBold'), local('Montserrat-ExtraBold'),
url('../fonts/montserrat-v14-latin-800.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-800.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-800.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-800.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-800.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 900;
src: url('../fonts/montserrat-v14-latin-900.eot'); /* IE9 Compat Modes */
src: local('Montserrat Black'), local('Montserrat-Black'),
url('../fonts/montserrat-v14-latin-900.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-900.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-900.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-900.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-900.svg#\1') format('svg'); /* Legacy iOS */
}
@font-face {
font-family: 'Montserrat';
font-style: italic;
font-weight: 900;
src: url('../fonts/montserrat-v14-latin-900italic.eot'); /* IE9 Compat Modes */
src: local('Montserrat Black Italic'), local('Montserrat-BlackItalic'),
url('../fonts/montserrat-v14-latin-900italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v14-latin-900italic.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v14-latin-900italic.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v14-latin-900italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v14-latin-900italic.svg#\1') format('svg'); /* Legacy iOS */
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,85 +0,0 @@
$(function() {
// register a handler to move the focus to the search bar
// upon pressing shift + "/" (i.e. "?")
$(document).on('keydown', function(e) {
if (e.shiftKey && e.keyCode == 191) {
e.preventDefault();
$("#search-input").focus();
}
});
$(document).ready(function() {
// do keyword highlighting
/* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */
var mark = function() {
var referrer = document.URL ;
var paramKey = "q" ;
if (referrer.indexOf("?") !== -1) {
var qs = referrer.substr(referrer.indexOf('?') + 1);
var qs_noanchor = qs.split('#')[0];
var qsa = qs_noanchor.split('&');
var keyword = "";
for (var i = 0; i < qsa.length; i++) {
var currentParam = qsa[i].split('=');
if (currentParam.length !== 2) {
continue;
}
if (currentParam[0] == paramKey) {
keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20"));
}
}
if (keyword !== "") {
$(".contents").unmark({
done: function() {
$(".contents").mark(keyword);
}
});
}
}
};
mark();
});
});
/* Search term highlighting ------------------------------*/
function matchedWords(hit) {
var words = [];
var hierarchy = hit._highlightResult.hierarchy;
// loop to fetch from lvl0, lvl1, etc.
for (var idx in hierarchy) {
words = words.concat(hierarchy[idx].matchedWords);
}
var content = hit._highlightResult.content;
if (content) {
words = words.concat(content.matchedWords);
}
// return unique words
var words_uniq = [...new Set(words)];
return words_uniq;
}
function updateHitURL(hit) {
var words = matchedWords(hit);
var url = "";
if (hit.anchor) {
url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor;
} else {
url = hit.url + '?q=' + escape(words.join(" "));
}
return url;
}

View File

@ -1,325 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<defs >
<font id="Montserrat" horiz-adv-x="626" ><font-face
font-family="Montserrat Thin"
units-per-em="1000"
panose-1="0 0 3 0 0 0 0 0 0 0"
ascent="968"
descent="-251"
alphabetic="0" />
<glyph unicode=" " glyph-name="space" horiz-adv-x="250" />
<glyph unicode="!" glyph-name="exclam" horiz-adv-x="242" d="M110 700H132L128 188H114L110 700ZM111 -3T103 5T95 23Q95 34 103 41T121 49Q132 49 139 42T147 23Q147 13 140 5T121 -3Q111 -3 103 5Z" />
<glyph unicode="&quot;" glyph-name="quotedbl" horiz-adv-x="334" d="M81 700H103L101 450H83L81 700ZM231 700H253L251 450H233L231 700Z" />
<glyph unicode="#" glyph-name="numbersign" horiz-adv-x="682" d="M496 471L466 229H615V210H464L438 0H418L444 210H204L178 0H158L184 210H35V229H186L216 471H66V490H218L244 700H264L238 490H478L504 700H524L498 490H646V471H496ZM476 471H236L206 229H446L476
471Z" />
<glyph unicode="$" glyph-name="dollar" horiz-adv-x="601" d="M543 124T518 85T441 22T311 -3V-120H292V-3Q219 -1 156 26T58 96L72 109Q105 70 164 44T292 16V343Q223 360 180 378T107 432T78 527Q78 598 132 648T292 703V820H311V703H312Q368 703 422 686T515
639L504 623Q463 653 413 668T313 684H311V358Q388 339 433 322T511 269T543 172Q543 124 518 85ZM98 475T124 444T190 395T292 362V683Q197 679 148 636T98 526Q98 475 124 444ZM415 17T469 61T523 172Q523 225 495 257T424 305T311 338V16Q415 17 469 61Z" />
<glyph unicode="%" glyph-name="percent" horiz-adv-x="800" d="M133 327T92 378T50 515Q50 600 91 651T199 703Q265 703 306 652T348 515Q348 430 307 379T199 327Q133 327 92 378ZM628 700H650L172 0H150L628 700ZM257 346T292 391T328 515Q328 593 293 638T199
684Q141 684 106 639T70 515Q70 437 105 392T199 346Q257 346 292 391ZM535 -3T494 48T452 185Q452 270 493 321T601 373Q667 373 708 322T750 185Q750 100 709 49T601 -3Q535 -3 494 48ZM659 16T694 61T730 185Q730 263 695 308T601 354Q543 354 508 309T472 185Q472
107 507 62T601 16Q659 16 694 61Z" />
<glyph unicode="&amp;" glyph-name="ampersand" horiz-adv-x="634" d="M612 -10L504 108Q424 -3 273 -3Q210 -3 161 18T84 78T56 168Q56 227 98 278T245 392L237 400Q185 456 167 491T149 568Q149 629 190 666T300 703Q365 703 403 670T441 578Q441 544 426 516T375
457T274 388L503 138Q540 197 558 290L575 286Q556 189 516 125L627 3L612 -10ZM169 531T186 498T255 409L262 402Q325 440 358 467T407 520T422 578Q422 627 390 655T300 684Q239 684 204 653T169 568Q169 531 186 498ZM416 14T492 121L258 378Q187 335 148 302T93
237T76 168Q76 99 130 57T273 14Q416 14 492 121Z" />
<glyph unicode="&apos;" glyph-name="quotesingle" horiz-adv-x="184" d="M81 700H103L101 450H83L81 700Z" />
<glyph unicode="(" glyph-name="parenleft" horiz-adv-x="311" d="M180 -102T152 17T123 274Q123 412 151 532T234 742H253Q143 557 143 274Q143 -9 253 -194H234Q180 -102 152 17Z" />
<glyph unicode=")" glyph-name="parenright" horiz-adv-x="311" d="M58 -194Q168 -9 168 274Q168 557 58 742H77Q131 653 159 533T188 274Q188 136 160 17T77 -194H58Z" />
<glyph unicode="*" glyph-name="asterisk" horiz-adv-x="358" d="M198 572L331 495L322 479L188 556V402H170V556L36 479L27 495L161 572L27 649L36 665L170 588V742H188V588L322 665L331 649L198 572Z" />
<glyph unicode="+" glyph-name="plus" horiz-adv-x="560" d="M485 340H290V150H270V340H75V359H270V550H290V359H485V340Z" />
<glyph unicode="," glyph-name="comma" horiz-adv-x="182" d="M102 49T109 41T117 23Q117 16 113 -6L80 -140H62L91 -3Q80 -2 73 5T65 23Q65 34 72 41T91 49Q102 49 109 41Z" />
<glyph unicode="-" glyph-name="hyphen" horiz-adv-x="380" d="M65 274H315V255H65V274Z" />
<glyph unicode="." glyph-name="period" horiz-adv-x="182" d="M81 -3T73 5T65 23Q65 34 73 41T91 49Q102 49 109 42T117 23Q117 13 110 5T91 -3Q81 -3 73 5Z" />
<glyph unicode="/" glyph-name="slash" horiz-adv-x="300" d="M310 842H330L0 -100H-20L310 842Z" />
<glyph unicode="0" glyph-name="zero" horiz-adv-x="652" d="M247 -3T187 40T93 164T59 350Q59 456 92 536T186 659T326 703Q405 703 465 660T559 536T593 350Q593 244 560 164T466 41T326 -3Q247 -3 187 40ZM399 16T455 57T542 173T573 350Q573 451 542 526T455
643T326 684Q253 684 197 643T110 527T79 350Q79 249 110 174T197 57T326 16Q399 16 455 57Z" />
<glyph unicode="1" glyph-name="one" horiz-adv-x="342" d="M209 700V0H190V681H10V700H209Z" />
<glyph unicode="2" glyph-name="two" horiz-adv-x="555" d="M511 19V0H43V15L346 322Q409 386 431 430T453 523Q453 598 403 641T258 684Q186 684 133 663T42 599L28 613Q109 703 258 703Q357 703 415 655T473 524Q473 471 449 423T360 309L74 19H511Z" />
<glyph unicode="3" glyph-name="three" horiz-adv-x="548" d="M365 387T427 335T490 192Q490 103 430 50T259 -3Q181 -3 116 24T19 96L32 109Q62 68 123 42T259 16Q361 16 415 63T470 192Q470 275 414 321T246 368H210V383L437 681H41V700H464V685L237 387H245Q365
387 427 335Z" />
<glyph unicode="4" glyph-name="four" horiz-adv-x="644" d="M627 208H471V0H451V208H46V223L440 700H464L73 227H451V410H471V227H627V208Z" />
<glyph unicode="5" glyph-name="five" horiz-adv-x="548" d="M367 397T435 346T503 196Q503 108 443 53T270 -3Q194 -3 129 24T32 96L45 109Q75 68 136 42T270 16Q374 16 428 65T483 196Q483 286 420 332T208 378H76L113 700H468V681H130L97 397H212Q367 397 435 346Z" />
<glyph unicode="6" glyph-name="six" horiz-adv-x="592" d="M430 406T492 351T555 202Q555 141 527 95T448 23T332 -3Q198 -3 129 90T59 350Q59 465 96 544T200 663T357 703Q452 703 506 670L496 653Q447 684 357 684Q228 684 154 599T79 352Q79 282 93 227Q106
310 170 358T325 406Q430 406 492 351ZM392 16T438 39T509 104T535 202Q535 286 479 336T325 387Q262 387 213 362T137 295T110 200Q110 154 135 112T211 43T332 16Q392 16 438 39Z" />
<glyph unicode="7" glyph-name="seven" horiz-adv-x="570" d="M522 700V685L209 0H186L498 681H56V540H36V700H522Z" />
<glyph unicode="8" glyph-name="eight" horiz-adv-x="624" d="M474 352T521 306T569 188Q569 99 501 48T311 -3Q190 -3 123 48T55 188Q55 259 102 305T234 366Q159 380 120 422T80 528Q80 609 142 656T311 703Q417 703 480 656T544 528Q544 465 504 423T388 366Q474
352 521 306ZM100 458T155 417T311 375Q411 375 467 416T524 528Q524 600 467 642T311 684Q214 684 157 642T100 529Q100 458 155 417ZM423 16T486 62T549 187Q549 265 486 310T311 356Q200 356 138 311T75 187Q75 108 137 62T311 16Q423 16 486 62Z" />
<glyph unicode="9" glyph-name="nine" horiz-adv-x="592" d="M394 703T463 610T533 350Q533 235 496 156T392 37T235 -3Q140 -3 86 30L96 47Q145 16 235 16Q364 16 438 101T513 348Q513 418 499 473Q486 390 422 342T267 294Q162 294 100 349T37 498Q37 559 65
605T144 677T260 703Q394 703 463 610ZM330 313T379 338T455 405T482 500Q482 546 457 588T381 657T260 684Q200 684 154 661T83 596T57 498Q57 414 113 364T267 313Q330 313 379 338Z" />
<glyph unicode=":" glyph-name="colon" horiz-adv-x="182" d="M81 468T73 476T65 494Q65 505 73 512T91 520Q102 520 109 513T117 494Q117 484 110 476T91 468Q81 468 73 476ZM81 -3T73 5T65 23Q65 34 73 41T91 49Q102 49 109 42T117 23Q117 13 110 5T91 -3Q81 -3 73 5Z" />
<glyph unicode=";" glyph-name="semicolon" horiz-adv-x="182" d="M81 468T73 476T65 494Q65 505 73 512T91 520Q102 520 109 513T117 494Q117 484 110 476T91 468Q81 468 73 476ZM102 49T109 41T117 23Q117 16 113 -6L80 -140H62L91 -3Q80 -2 73 5T65 23Q65 34
72 41T91 49Q102 49 109 41Z" />
<glyph unicode="&lt;" glyph-name="less" horiz-adv-x="560" d="M485 510L98 350L485 190V168L75 339V361L485 532V510Z" />
<glyph unicode="=" glyph-name="equal" horiz-adv-x="560" d="M75 469H485V450H75V469ZM75 250H485V231H75V250Z" />
<glyph unicode="&gt;" glyph-name="greater" horiz-adv-x="560" d="M485 361V339L75 168V190L462 350L75 510V532L485 361Z" />
<glyph unicode="?" glyph-name="question" horiz-adv-x="554" d="M250 231T264 263T298 318T351 370Q383 398 401 418T432 468T445 535Q445 602 394 643T250 684Q178 684 125 663T34 599L20 613Q101 703 250 703Q315 703 363 682T438 623T465 536Q465 494 452
462T418 408T365 356Q333 327 315 307T283 257T270 188H250Q250 231 264 263ZM250 -3T242 5T234 23Q234 34 242 41T260 49Q271 49 278 42T286 23Q286 13 279 5T260 -3Q250 -3 242 5Z" />
<glyph unicode="@" glyph-name="at" horiz-adv-x="1032" d="M649 703T752 648T914 491T973 259Q973 177 955 118T906 28T834 -3Q792 -3 767 22T742 89V158Q716 84 654 41T511 -3Q441 -3 384 30T293 124T260 259Q260 334 293 393T383 486T511 520Q591 520 653 477T742
360V517H762V99Q762 56 781 36T834 16Q868 16 895 44T937 128T953 259Q953 385 898 481T743 631T517 684Q390 684 290 630T135 479T79 254Q79 129 134 31T288 -122T513 -177Q560 -177 611 -166T702 -133L710 -151Q668 -174 615 -185T513 -197Q381 -197 278 -140T117
20T59 254Q59 386 117 488T280 647T517 703Q649 703 752 648ZM576 16T629 47T712 133T742 259Q742 329 712 384T629 470T511 501Q446 501 393 471T310 385T280 259Q280 189 310 134T393 47T511 16Q576 16 629 47Z" />
<glyph unicode="A" glyph-name="A" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549Z" />
<glyph unicode="B" glyph-name="B" horiz-adv-x="748" d="M683 335T683 183Q683 94 620 47T430 0H133V700H410Q520 700 582 655T645 523Q645 457 609 416T507 359Q683 335 683 183ZM153 681V365H414Q515 365 570 405T625 523Q625 600 570 640T414 681H153ZM663
19T663 183Q663 266 606 306T434 346H153V19H434Q663 19 663 183Z" />
<glyph unicode="C" glyph-name="C" horiz-adv-x="711" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q489 703 550 681T656 614L644 600Q556 684 418 684Q323 684 246 640T124 520T79 350Q79 257 123 181T245 60T418 16Q555 16 644 101L656
87Q612 43 550 20T418 -3Q317 -3 235 43Z" />
<glyph unicode="D" glyph-name="D" horiz-adv-x="826" d="M133 700H398Q507 700 590 655T720 530T767 350Q767 250 721 170T591 45T398 0H133V700ZM396 19Q501 19 580 61T703 179T747 350Q747 445 704 520T581 638T396 681H153V19H396Z" />
<glyph unicode="E" glyph-name="E" horiz-adv-x="668" d="M599 19V0H133V700H584V681H153V365H539V346H153V19H599Z" />
<glyph unicode="F" glyph-name="F" horiz-adv-x="629" d="M153 681V345H539V326H153V0H133V700H584V681H153Z" />
<glyph unicode="G" glyph-name="G" horiz-adv-x="774" d="M643 343H662V87Q618 43 556 20T421 -3Q318 -3 236 43T106 169T59 350Q59 450 106 530T235 657T421 703Q494 703 556 681T662 614L650 600Q562 684 421 684Q325 684 247 640T124 520T79 350Q79 257 123
181T246 60T421 16Q560 16 643 95V343Z" />
<glyph unicode="H" glyph-name="H" horiz-adv-x="816" d="M683 700V0H663V346H153V0H133V700H153V365H663V700H683Z" />
<glyph unicode="I" glyph-name="I" horiz-adv-x="286" d="M133 700H153V0H133V700Z" />
<glyph unicode="J" glyph-name="J" horiz-adv-x="477" d="M125 -3T79 23T4 96L18 108Q47 64 88 40T179 16Q256 16 293 60T330 196V681H68V700H350V194Q350 -3 178 -3Q125 -3 79 23Z" />
<glyph unicode="K" glyph-name="K" horiz-adv-x="693" d="M327 365L153 186V0H133V700H153V213L627 700H654L342 379L677 0H650L327 365Z" />
<glyph unicode="L" glyph-name="L" horiz-adv-x="580" d="M133 700H153V19H570V0H133V700Z" />
<glyph unicode="M" glyph-name="M" horiz-adv-x="956" d="M823 700V0H803V657L484 99H472L153 655V0H133V700H150L478 126L806 700H823Z" />
<glyph unicode="N" glyph-name="N" horiz-adv-x="816" d="M683 700V0H666L153 663V0H133V700H150L663 37V700H683Z" />
<glyph unicode="O" glyph-name="O" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757 444 713 520T591
640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59Z" />
<glyph unicode="P" glyph-name="P" horiz-adv-x="710" d="M499 700T572 640T645 470Q645 361 572 301T370 240H153V0H133V700H370Q499 700 572 640ZM494 259T559 314T625 470Q625 571 560 626T372 681H153V259H372Q494 259 559 314Z" />
<glyph unicode="Q" glyph-name="Q" horiz-adv-x="836" d="M807 -48Q776 -85 736 -104T648 -124Q596 -124 544 -95T431 -3H418Q317 -3 235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 257 736 181T623 56T459 -1Q557
-105 648 -105Q734 -105 793 -34L807 -48ZM79 257T123 181T245 60T418 16Q513 16 590 60T712 180T757 350Q757 443 713 519T591 640T418 684Q323 684 246 640T124 520T79 350Q79 257 123 181Z" />
<glyph unicode="R" glyph-name="R" horiz-adv-x="716" d="M630 0L452 247Q417 240 370 240H153V0H133V700H370Q499 700 572 640T645 470Q645 386 600 330T473 252L655 0H630ZM372 259Q494 259 559 314T625 470Q625 571 560 626T372 681H153V259H372Z" />
<glyph unicode="S" glyph-name="S" horiz-adv-x="601" d="M228 -3T161 24T58 96L72 109Q106 69 169 43T303 16Q412 16 467 59T523 172Q523 226 494 258T423 306T308 339Q231 358 186 375T110 429T78 527Q78 575 103 615T181 679T312 703Q368 703 422 686T515 639L504
623Q463 653 413 668T313 684Q208 684 153 640T98 526Q98 472 127 440T199 391T315 357Q391 338 436 321T512 268T543 172Q543 124 517 84T438 21T304 -3Q228 -3 161 24Z" />
<glyph unicode="T" glyph-name="T" horiz-adv-x="548" d="M264 681H4V700H544V681H284V0H264V681Z" />
<glyph unicode="U" glyph-name="U" horiz-adv-x="794" d="M269 -3T198 72T127 293V700H147V294Q147 156 211 86T397 16Q518 16 582 86T647 294V700H667V293Q667 147 596 72T397 -3Q269 -3 198 72Z" />
<glyph unicode="V" glyph-name="V" horiz-adv-x="670" d="M660 700L345 0H325L10 700H33L335 27L637 700H660Z" />
<glyph unicode="W" glyph-name="W" horiz-adv-x="1080" d="M1035 700L795 0H775L540 672L305 0H285L45 700H67L296 32L530 700H550L785 30L1014 700H1035Z" />
<glyph unicode="X" glyph-name="X" horiz-adv-x="621" d="M571 0L310 347L49 0H25L298 362L45 700H70L311 377L552 700H576L323 362L596 0H571Z" />
<glyph unicode="Y" glyph-name="Y" horiz-adv-x="610" d="M315 238V0H295V238L10 700H33L305 259L577 700H600L315 238Z" />
<glyph unicode="Z" glyph-name="Z" horiz-adv-x="639" d="M600 19V0H50V15L562 681H55V700H590V685L78 19H600Z" />
<glyph unicode="[" glyph-name="bracketleft" horiz-adv-x="288" d="M133 742H263V723H153V-175H263V-194H133V742Z" />
<glyph unicode="\" glyph-name="backslash" horiz-adv-x="300" d="M300 -100L-30 842H-10L320 -100H300Z" />
<glyph unicode="]" glyph-name="bracketright" horiz-adv-x="288" d="M25 -194V-175H135V723H25V742H155V-194H25Z" />
<glyph unicode="^" glyph-name="asciicircum" horiz-adv-x="562" d="M441 145L281 532L121 145H99L270 555H292L463 145H441Z" />
<glyph unicode="_" glyph-name="underscore" horiz-adv-x="500" d="M0 0H500V-19H0V0Z" />
<glyph unicode="`" glyph-name="grave" horiz-adv-x="600" d="M165 717H205L345 607H315L165 717Z" />
<glyph unicode="a" glyph-name="a" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169 499T280 520Q370
520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148Z" />
<glyph unicode="b" glyph-name="b" horiz-adv-x="671" d="M436 520T493 487T584 394T617 259Q617 184 584 124T494 31T366 -3Q285 -3 223 40T135 158V0H115V742H135V360Q161 433 223 476T366 520Q436 520 493 487ZM431 16T484 47T567 133T597 259Q597 329 567
384T484 470T366 501Q301 501 248 471T165 385T135 259Q135 189 165 134T248 47T366 16Q431 16 484 47Z" />
<glyph unicode="c" glyph-name="c" horiz-adv-x="545" d="M235 -3T177 30T87 123T54 259Q54 335 86 394T177 487T308 520Q365 520 413 499T494 436L480 421Q451 461 406 481T308 501Q241 501 188 471T104 385T74 259Q74 188 104 133T187 47T308 16Q361 16 406
36T480 96L494 81Q462 40 414 19T308 -3Q235 -3 177 30Z" />
<glyph unicode="d" glyph-name="d" horiz-adv-x="671" d="M556 742V0H536V158Q510 84 448 41T305 -3Q235 -3 178 30T87 124T54 259Q54 334 87 393T177 486T305 520Q385 520 447 477T536 360V742H556ZM370 16T423 47T506 133T536 259Q536 329 506 384T423 470T305
501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47Z" />
<glyph unicode="e" glyph-name="e" horiz-adv-x="587" d="M533 259H73Q73 189 104 134T189 47T312 16Q365 16 411 36T488 96L502 82Q468 41 418 19T312 -3Q238 -3 180 30T88 124T54 259Q54 334 85 393T170 486T293 520Q360 520 415 487T501 396T533 264V259ZM233
501T184 472T106 392T73 278H514Q511 341 481 392T402 472T293 501Q233 501 184 472Z" />
<glyph unicode="f" glyph-name="f" horiz-adv-x="311" d="M197 726T170 697T143 613V517H318V498H143V0H123V498H23V517H123V618Q123 676 156 710T248 745Q277 745 304 736T349 708L335 694Q301 726 249 726Q197 726 170 697Z" />
<glyph unicode="g" glyph-name="g" horiz-adv-x="677" d="M562 517V46Q562 -78 503 -137T323 -197Q252 -197 192 -174T94 -111L108 -97Q148 -136 203 -157T323 -178Q435 -178 488 -125T542 43V173Q515 102 453 60T308 17Q236 17 178 49T87 139T54 269Q54 341 87
398T178 488T308 520Q390 520 452 478T542 366V517H562ZM375 36T428 65T512 148T542 269Q542 336 512 389T429 471T308 501Q241 501 188 472T104 389T74 269Q74 202 104 149T187 66T308 36Q375 36 428 65Z" />
<glyph unicode="h" glyph-name="h" horiz-adv-x="668" d="M449 520T504 465T559 305V0H539V305Q539 400 491 450T353 501Q252 501 194 441T135 281V0H115V742H135V379Q159 445 215 482T352 520Q449 520 504 465Z" />
<glyph unicode="i" glyph-name="i" horiz-adv-x="250" d="M115 517H135V0H115V517ZM114 660T107 668T99 686Q99 697 106 704T125 712Q135 712 143 705T151 686Q151 676 143 668T125 660Q114 660 107 668Z" />
<glyph unicode="j" glyph-name="j" horiz-adv-x="255" d="M-13 -197T-41 -188T-86 -160L-72 -146Q-38 -178 17 -178Q67 -178 93 -149T120 -65V517H140V-70Q140 -128 108 -162T18 -197Q-13 -197 -41 -188ZM119 660T112 668T104 686Q104 697 111 704T130 712Q140
712 148 705T156 686Q156 676 148 668T130 660Q119 660 112 668Z" />
<glyph unicode="k" glyph-name="k" horiz-adv-x="570" d="M288 299L135 160V0H115V742H135V184L500 517H529L304 311L552 0H526L288 299Z" />
<glyph unicode="l" glyph-name="l" horiz-adv-x="250" d="M115 742H135V0H115V742Z" />
<glyph unicode="m" glyph-name="m" horiz-adv-x="1068" d="M852 520T905 465T959 305V0H939V305Q939 400 892 450T759 501Q661 501 604 441T547 281V0H527V305Q527 400 480 450T347 501Q249 501 192 441T135 281V0H115V517H135V380Q158 446 213 483T346 520Q425
520 476 481T542 366Q562 437 618 478T758 520Q852 520 905 465Z" />
<glyph unicode="n" glyph-name="n" horiz-adv-x="668" d="M449 520T504 465T559 305V0H539V305Q539 400 491 450T353 501Q252 501 194 441T135 281V0H115V517H135V379Q159 445 215 482T352 520Q449 520 504 465Z" />
<glyph unicode="o" glyph-name="o" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329 506 384T423
470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47Z" />
<glyph unicode="p" glyph-name="p" horiz-adv-x="671" d="M436 520T493 487T584 393T617 258Q617 183 584 124T494 31T366 -3Q286 -3 224 40T135 157V-194H115V517H135V359Q161 433 223 476T366 520Q436 520 493 487ZM431 16T484 46T567 132T597 258Q597 328 567
383T484 470T366 501Q301 501 248 470T165 384T135 258Q135 188 165 133T248 47T366 16Q431 16 484 46Z" />
<glyph unicode="q" glyph-name="q" horiz-adv-x="671" d="M556 517V-194H536V157Q510 84 448 41T305 -3Q235 -3 178 30T87 123T54 258Q54 333 87 393T177 486T305 520Q386 520 448 477T536 359V517H556ZM370 16T423 46T506 132T536 258Q536 328 506 383T423 470T305
501Q240 501 187 470T104 384T74 258Q74 188 104 133T187 47T305 16Q370 16 423 46Z" />
<glyph unicode="r" glyph-name="r" horiz-adv-x="383" d="M157 449T209 484T338 520V500H332Q239 500 187 441T135 278V0H115V517H135V383Q157 449 209 484Z" />
<glyph unicode="s" glyph-name="s" horiz-adv-x="463" d="M172 -3T117 17T32 68L44 84Q74 55 124 36T234 16Q322 16 364 46T406 131Q406 170 384 192T329 225T239 247Q178 258 141 270T78 310T52 387Q52 443 98 481T235 520Q283 520 330 506T406 467L394 451Q364
475 322 488T235 501Q154 501 114 470T73 387Q73 346 96 323T153 288T243 267Q304 255 340 243T401 205T426 131Q426 70 377 34T234 -3Q172 -3 117 17Z" />
<glyph unicode="t" glyph-name="t" horiz-adv-x="388" d="M349 34Q332 16 305 7T248 -3Q188 -3 156 31T123 124V498H23V517H123V630H143V517H318V498H143V129Q143 74 170 45T249 16Q301 16 335 48L349 34Z" />
<glyph unicode="u" glyph-name="u" horiz-adv-x="664" d="M549 517V0H529V137Q506 71 452 34T321 -3Q221 -3 165 52T109 212V517H129V212Q129 117 179 67T320 16Q417 16 473 76T529 236V517H549Z" />
<glyph unicode="v" glyph-name="v" horiz-adv-x="508" d="M502 517L264 0H244L6 517H29L254 23L479 517H502Z" />
<glyph unicode="w" glyph-name="w" horiz-adv-x="838" d="M826 517L627 0H609L419 489L228 0H211L12 517H32L219 24L409 517H428L618 24L805 517H826Z" />
<glyph unicode="x" glyph-name="x" horiz-adv-x="498" d="M444 0L249 253L53 0H28L236 268L40 517H65L248 282L431 517H455L260 268L470 0H444Z" />
<glyph unicode="y" glyph-name="y" horiz-adv-x="508" d="M502 517L227 -83Q199 -145 164 -171T81 -197Q11 -197 -31 -151L-16 -135Q5 -158 28 -168T82 -178Q122 -178 151 -156T207 -77L243 2L6 517H29L254 23L479 517H502Z" />
<glyph unicode="z" glyph-name="z" horiz-adv-x="491" d="M443 19V0H46V15L410 498H51V517H438V502L74 19H443Z" />
<glyph unicode="{" glyph-name="braceleft" horiz-adv-x="300" d="M165 309T158 295T133 274Q150 267 157 253T165 212V-92Q165 -175 243 -175H275V-194H250Q145 -194 145 -92V212Q145 265 100 265H65V284H100Q145 284 145 336V640Q145 742 250 742H275V723H243Q165
723 165 640V336Q165 309 158 295Z" />
<glyph unicode="|" glyph-name="bar" horiz-adv-x="286" d="M133 742H153V-194H133V742Z" />
<glyph unicode="}" glyph-name="braceright" horiz-adv-x="300" d="M235 284V265H200Q155 265 155 212V-92Q155 -194 50 -194H25V-175H57Q135 -175 135 -92V212Q135 239 142 253T167 274Q150 281 143 295T135 336V640Q135 723 57 723H25V742H50Q155 742 155 640V336Q155
284 200 284H235Z" />
<glyph unicode="~" glyph-name="asciitilde" horiz-adv-x="560" d="M350 286T327 300T272 344Q243 371 224 383T178 396Q137 396 113 367T87 289H69Q72 347 101 380T178 414Q210 414 233 400T288 356Q317 329 336 317T382 304Q423 304 447 333T473 411H491Q488
353 459 320T382 286Q350 286 327 300Z" />
<glyph unicode="&#xa0;" glyph-name="uni00A0" horiz-adv-x="250" />
<glyph unicode="&#xa1;" glyph-name="exclamdown" horiz-adv-x="242" d="M132 520T139 513T147 494Q147 484 140 476T121 468Q111 468 103 476T95 494Q95 505 103 512T121 520Q132 520 139 513ZM132 -154H110L114 329H128L132 -154Z" />
<glyph unicode="&#xa2;" glyph-name="cent" horiz-adv-x="545" d="M364 17T407 37T480 96L494 81Q462 41 415 20T312 -3V-120H293V-3Q224 0 170 34T85 127T54 259Q54 332 84 390T169 483T293 520V637H312V520Q367 519 414 498T494 436L480 421Q451 460 408 480T312
501V16Q364 17 407 37ZM74 191T102 137T180 51T293 16V501Q230 498 180 466T102 381T74 259Q74 191 102 137Z" />
<glyph unicode="&#xa3;" glyph-name="sterling" horiz-adv-x="618" d="M170 19H590V0H30V19H150V341H30V359H150V482Q150 584 212 643T395 703Q523 703 600 642L587 626Q513 684 395 684Q281 684 226 631T170 479V359H469V341H170V19Z" />
<glyph unicode="&#xa4;" glyph-name="currency" horiz-adv-x="700" d="M633 263T612 214T553 129L661 20L647 6L538 115Q500 82 452 64T350 46Q297 46 250 64T163 116L53 6L39 20L148 130Q111 167 91 215T70 316Q70 370 90 418T148 505L39 615L53 629L163 519Q202
552 249 570T350 589Q403 589 451 571T538 520L647 629L661 615L553 506Q591 468 612 419T633 316Q633 263 612 214ZM90 249T125 192T220 100T350 66Q421 66 481 100T577 191T613 316Q613 384 578 442T482 535T350 569Q280 569 220 535T125 443T90 316Q90 249 125
192Z" />
<glyph unicode="&#xa5;" glyph-name="yen" horiz-adv-x="670" d="M359 313H585V295H345V175H585V157H345V0H325V157H85V175H325V295H85V313H311L10 700H33L335 314L637 700H660L359 313Z" />
<glyph unicode="&#xa6;" glyph-name="brokenbar" horiz-adv-x="286" d="M133 742H153V392H133V742ZM133 156H153V-194H133V156Z" />
<glyph unicode="&#xa7;" glyph-name="section" horiz-adv-x="471" d="M430 236T402 202T329 152Q366 135 386 108T406 36Q406 -30 357 -66T224 -103Q169 -103 115 -83T32 -32L44 -16Q73 -45 122 -64T224 -84Q302 -84 344 -54T386 38Q386 79 364 103T310 140T224
167Q165 182 130 196T71 239T46 317Q46 364 74 398T147 447Q110 464 90 491T70 562Q70 630 120 666T263 703Q311 703 357 689T434 650L422 634Q392 658 350 671T263 684Q179 684 135 654T90 562Q90 521 112 497T166 460T252 433Q311 418 346 404T405 361T430 283Q430
236 402 202ZM350 172T380 203T411 283Q411 325 389 350T333 389T245 416Q197 428 175 436Q126 426 96 396T65 317Q65 275 87 250T142 212T231 184Q242 181 264 175T302 163Q350 172 380 203Z" />
<glyph unicode="&#xa8;" glyph-name="dieresis" horiz-adv-x="600" d="M207 641T200 649T192 667Q192 678 199 685T218 693Q228 693 236 686T244 667Q244 657 236 649T218 641Q207 641 200 649ZM371 641T364 649T356 667Q356 678 363 685T382 693Q392 693 400
686T408 667Q408 657 400 649T382 641Q371 641 364 649Z" />
<glyph unicode="&#xa9;" glyph-name="copyright" horiz-adv-x="824" d="M313 -3T233 44T106 172T59 350Q59 447 105 528T233 656T413 703Q512 703 592 657T719 531T765 352Q765 254 718 173T590 44T411 -3Q313 -3 233 44ZM504 16T580 60T701 182T746 352Q746 445
703 521T583 640T413 684Q320 684 243 640T122 519T78 350Q78 258 122 182T242 61T411 16Q504 16 580 60ZM361 139T314 166T241 241T214 350Q214 411 240 459T314 534T419 561Q465 561 504 544T570 493L555 478Q531 510 496 526T418 542Q365 542 324 518T258 450T234
350Q234 294 258 251T323 183T418 158Q460 158 495 174T555 222L570 207Q543 174 504 157T419 139Q361 139 314 166Z" />
<glyph unicode="&#xaa;" glyph-name="ordfeminine" horiz-adv-x="394" d="M249 744T280 716T312 633V434H293V499Q278 468 246 450T167 432Q112 432 81 455T49 519Q49 556 78 579T170 602H292V633Q292 726 189 726Q153 726 122 715T69 685L59 699Q84 720 118 732T189
744Q249 744 280 716ZM259 448T292 523V587H170Q118 587 93 569T68 520Q68 487 95 468T170 448Q259 448 292 523Z" />
<glyph unicode="&#xab;" glyph-name="guillemotleft" horiz-adv-x="423" d="M58 259L205 444H228L82 259L228 74H205L58 259ZM208 259L355 444H378L232 259L378 74H355L208 259Z" />
<glyph unicode="&#xac;" glyph-name="logicalnot" horiz-adv-x="560" d="M485 159H465V340H75V359H485V159Z" />
<glyph unicode="&#xad;" glyph-name="uni00AD" horiz-adv-x="380" d="M65 274H315V255H65V274Z" />
<glyph unicode="&#xae;" glyph-name="registered" horiz-adv-x="824" d="M512 703T592 657T719 531T765 352Q765 254 718 173T590 44T411 -3Q313 -3 233 44T106 172T59 350Q59 447 105 528T233 656T413 703Q512 703 592 657ZM504 16T580 60T701 182T746 352Q746
445 703 521T583 640T413 684Q320 684 243 640T122 519T78 350Q78 258 122 182T242 61T411 16Q504 16 580 60ZM586 377T560 344T485 298L586 142H562L464 294Q444 292 433 292H303V142H283V558H433Q503 558 544 522T586 425Q586 377 560 344ZM495 311T530 341T566
425Q566 479 531 509T431 539H302V311H431Q495 311 530 341Z" />
<glyph unicode="&#xaf;" glyph-name="overscore" horiz-adv-x="600" d="M164 672H436V652H164V672Z" />
<glyph unicode="&#xb0;" glyph-name="degree" horiz-adv-x="420" d="M169 403T135 423T80 477T60 553Q60 594 80 628T134 683T210 703Q251 703 285 683T340 629T360 553Q360 512 340 478T286 423T210 403Q169 403 135 423ZM246 421T276 438T323 486T341 553Q341
589 324 619T276 667T210 685Q174 685 144 668T97 620T79 553Q79 517 96 487T144 439T210 421Q246 421 276 438Z" />
<glyph unicode="&#xb1;" glyph-name="plusminus" horiz-adv-x="560" d="M485 359V340H290V150H270V340H75V359H270V550H290V359H485ZM75 19H485V0H75V19Z" />
<glyph unicode="&#xb2;" glyph-name="uni00B2" horiz-adv-x="430" d="M368 345V327H52V341L252 520Q295 558 310 584T326 637Q326 676 292 701T191 726Q100 726 53 678L40 690Q91 744 191 744Q267 744 306 714T345 638Q345 606 328 578T266 509L83 345H368Z" />
<glyph unicode="&#xb3;" glyph-name="uni00B3" horiz-adv-x="430" d="M279 558T320 527T361 442Q361 389 320 357T203 325Q149 325 105 340T41 382L51 397Q71 373 111 358T203 343Q272 343 307 369T342 442Q342 488 307 514T202 541H170V556L318 724H45V742H344V728L194
558H203Q279 558 320 527Z" />
<glyph unicode="&#xb4;" glyph-name="acute" horiz-adv-x="600" d="M395 717H435L285 607H255L395 717Z" />
<glyph unicode="&#xb5;" glyph-name="uni00B5" horiz-adv-x="670" d="M555 517V0H535V137Q511 70 457 34T327 -3Q257 -3 208 25T135 109V-194H115V517H135V212Q135 117 185 67T326 16Q423 16 479 76T535 236V517H555Z" />
<glyph unicode="&#xb6;" glyph-name="paragraph" horiz-adv-x="600" d="M225 419Q134 419 80 463T25 581Q25 656 79 699T225 742H467V-100H447V723H245V-100H225V419Z" />
<glyph unicode="&#xb7;" glyph-name="middot" horiz-adv-x="222" d="M101 238T93 246T85 264Q85 275 93 282T111 290Q122 290 129 283T137 264Q137 254 130 246T111 238Q101 238 93 246Z" />
<glyph unicode="&#xb8;" glyph-name="cedilla" horiz-adv-x="600" d="M241 -213T210 -186L221 -171Q246 -194 283 -194Q315 -194 335 -178T355 -134Q355 -107 336 -91T284 -74H268L290 5H309L292 -56Q330 -58 352 -79T375 -134Q375 -170 350 -191T284 -213Q241
-213 210 -186Z" />
<glyph unicode="&#xb9;" glyph-name="uni00B9" horiz-adv-x="430" d="M362 345V327H90V345H223V724H97V742H242V345H362Z" />
<glyph unicode="&#xba;" glyph-name="ordmasculine" horiz-adv-x="407" d="M157 432T120 452T61 507T40 588Q40 633 61 668T119 724T203 744Q249 744 286 724T345 669T366 588Q366 543 345 508T287 452T203 432Q157 432 120 452ZM265 450T306 488T347 588Q347
649 306 687T203 726Q141 726 100 688T59 588Q59 527 100 489T203 450Q265 450 306 488Z" />
<glyph unicode="&#xbb;" glyph-name="guillemotright" horiz-adv-x="423" d="M45 74L191 259L45 444H68L215 259L68 74H45ZM195 74L341 259L195 444H218L365 259L218 74H195Z" />
<glyph unicode="&#xbc;" glyph-name="onequarter" horiz-adv-x="1020" d="M362 303V285H90V303H223V682H97V700H242V303H362ZM738 700H760L282 0H260L738 700ZM984 120H883V0H864V120H626V134L842 415H865L651 138H864V243H883V138H984V120Z" />
<glyph unicode="&#xbd;" glyph-name="onehalf" horiz-adv-x="1020" d="M362 303V285H90V303H223V682H97V700H242V303H362ZM738 700H760L282 0H260L738 700ZM958 18V0H642V14L842 193Q885 231 900 257T916 310Q916 349 882 374T781 399Q690 399 643 351L630 363Q681
417 781 417Q857 417 896 387T935 311Q935 279 918 251T856 182L673 18H958Z" />
<glyph unicode="&#xbe;" glyph-name="threequarters" horiz-adv-x="1020" d="M279 516T320 485T361 400Q361 347 320 315T203 283Q149 283 105 298T41 340L51 355Q71 331 111 316T203 301Q272 301 307 327T342 400Q342 446 307 472T202 499H170V514L318 682H45V700H344V686L194
516H203Q279 516 320 485ZM738 700H760L282 0H260L738 700ZM984 120H883V0H864V120H626V134L842 415H865L651 138H864V243H883V138H984V120Z" />
<glyph unicode="&#xbf;" glyph-name="questiondown" horiz-adv-x="554" d="M284 468T276 476T268 494Q268 505 276 512T294 520Q305 520 312 513T320 494Q320 484 313 476T294 468Q284 468 276 476ZM239 -157T191 -137T116 -80T89 1Q89 41 102 71T136 122T189
171Q220 197 239 217T271 265T284 329H304Q304 288 290 258T256 206T203 158Q171 131 153 112T122 66T109 2Q109 -37 131 -69T198 -119T304 -138Q376 -138 429 -117T520 -53L534 -67Q453 -157 304 -157Q239 -157 191 -137Z" />
<glyph unicode="&#xc0;" glyph-name="Agrave" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549ZM209 867H249L389 757H359L209 867Z" />
<glyph unicode="&#xc1;" glyph-name="Aacute" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549ZM439 867H479L329 757H299L439 867Z" />
<glyph unicode="&#xc2;" glyph-name="Acircumflex" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549ZM455 757L344 850L233 757H206L328 867H360L482 757H455Z" />
<glyph unicode="&#xc3;" glyph-name="Atilde" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549ZM387 769T372 778T336 807Q320 822 308 830T281 838Q257 838 243 820T227 771H208Q210 810 229 833T281
857Q301 857 316 848T352 819Q368 804 380 796T407 788Q431 788 445 805T461 853H480Q478 815 459 792T407 769Q387 769 372 778Z" />
<glyph unicode="&#xc4;" glyph-name="Adieresis" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549ZM251 791T244 799T236 817Q236 828 243 835T262 843Q272 843 280 836T288 817Q288 807 280 799T262 791Q251
791 244 799ZM415 791T408 799T400 817Q400 828 407 835T426 843Q436 843 444 836T452 817Q452 807 444 799T426 791Q415 791 408 799Z" />
<glyph unicode="&#xc5;" glyph-name="Aring" horiz-adv-x="688" d="M558 211H130L32 0H9L334 700H354L679 0H656L558 211ZM549 230L344 673L139 230H549ZM303 780T277 806T251 870Q251 908 277 935T343 963Q382 963 409 936T436 870Q436 833 410 807T343 780Q303
780 277 806ZM375 799T395 819T416 870Q416 900 395 922T343 944Q312 944 292 923T271 870Q271 840 291 820T343 799Q375 799 395 819Z" />
<glyph unicode="&#xc6;" glyph-name="AE" horiz-adv-x="1005" d="M936 19V0H470V211H166L32 0H9L454 700H921V681H490V365H876V346H490V19H936ZM470 230V681H464L178 230H470Z" />
<glyph unicode="&#xc7;" glyph-name="Ccedilla" horiz-adv-x="711" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q489 703 550 681T656 614L644 600Q556 684 418 684Q323 684 246 640T124 520T79 350Q79 257 123 181T245 60T418 16Q555 16
644 101L656 87Q612 43 550 20T418 -3Q317 -3 235 43ZM349 -213T318 -186L329 -171Q354 -194 391 -194Q423 -194 443 -178T463 -134Q463 -107 444 -91T392 -74H376L398 5H417L400 -56Q438 -58 460 -79T483 -134Q483 -170 458 -191T392 -213Q349 -213 318 -186Z"
/>
<glyph unicode="&#xc8;" glyph-name="Egrave" horiz-adv-x="668" d="M599 19V0H133V700H584V681H153V365H539V346H153V19H599ZM224 867H264L404 757H374L224 867Z" />
<glyph unicode="&#xc9;" glyph-name="Eacute" horiz-adv-x="668" d="M599 19V0H133V700H584V681H153V365H539V346H153V19H599ZM454 867H494L344 757H314L454 867Z" />
<glyph unicode="&#xca;" glyph-name="Ecircumflex" horiz-adv-x="668" d="M599 19V0H133V700H584V681H153V365H539V346H153V19H599ZM470 757L359 850L248 757H221L343 867H375L497 757H470Z" />
<glyph unicode="&#xcb;" glyph-name="Edieresis" horiz-adv-x="668" d="M599 19V0H133V700H584V681H153V365H539V346H153V19H599ZM266 791T259 799T251 817Q251 828 258 835T277 843Q287 843 295 836T303 817Q303 807 295 799T277 791Q266 791 259 799ZM430 791T423
799T415 817Q415 828 422 835T441 843Q451 843 459 836T467 817Q467 807 459 799T441 791Q430 791 423 799Z" />
<glyph unicode="&#xcc;" glyph-name="Igrave" horiz-adv-x="286" d="M133 700H153V0H133V700ZM8 867H48L188 757H158L8 867Z" />
<glyph unicode="&#xcd;" glyph-name="Iacute" horiz-adv-x="286" d="M133 700H153V0H133V700ZM238 867H278L128 757H98L238 867Z" />
<glyph unicode="&#xce;" glyph-name="Icircumflex" horiz-adv-x="286" d="M133 700H153V0H133V700ZM254 757L143 850L32 757H5L127 867H159L281 757H254Z" />
<glyph unicode="&#xcf;" glyph-name="Idieresis" horiz-adv-x="286" d="M133 700H153V0H133V700ZM50 791T43 799T35 817Q35 828 42 835T61 843Q71 843 79 836T87 817Q87 807 79 799T61 791Q50 791 43 799ZM214 791T207 799T199 817Q199 828 206 835T225 843Q235
843 243 836T251 817Q251 807 243 799T225 791Q214 791 207 799Z" />
<glyph unicode="&#xd0;" glyph-name="Eth" horiz-adv-x="826" d="M133 700H398Q507 700 590 655T720 530T767 350Q767 250 721 170T591 45T398 0H133V700ZM396 19Q501 19 580 61T703 179T747 350Q747 445 704 520T581 638T396 681H153V19H396ZM20 365H380V346H20V365Z" />
<glyph unicode="&#xd1;" glyph-name="Ntilde" horiz-adv-x="816" d="M683 700V0H666L153 663V0H133V700H150L663 37V700H683ZM451 769T436 778T400 807Q384 822 372 830T345 838Q321 838 307 820T291 771H272Q274 810 293 833T345 857Q365 857 380 848T416 819Q432
804 444 796T471 788Q495 788 509 805T525 853H544Q542 815 523 792T471 769Q451 769 436 778Z" />
<glyph unicode="&#xd2;" glyph-name="Ograve" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757 444
713 520T591 640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59ZM283 867H323L463 757H433L283 867Z" />
<glyph unicode="&#xd3;" glyph-name="Oacute" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757 444
713 520T591 640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59ZM513 867H553L403 757H373L513 867Z" />
<glyph unicode="&#xd4;" glyph-name="Ocircumflex" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757
444 713 520T591 640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59ZM529 757L418 850L307 757H280L402 867H434L556 757H529Z" />
<glyph unicode="&#xd5;" glyph-name="Otilde" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757 444
713 520T591 640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59ZM461 769T446 778T410 807Q394 822 382 830T355 838Q331 838 317 820T301 771H282Q284 810 303 833T355 857Q375 857 390 848T426 819Q442 804 454 796T481
788Q505 788 519 805T535 853H554Q552 815 533 792T481 769Q461 769 446 778Z" />
<glyph unicode="&#xd6;" glyph-name="Odieresis" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757 444
713 520T591 640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59ZM325 791T318 799T310 817Q310 828 317 835T336 843Q346 843 354 836T362 817Q362 807 354 799T336 791Q325 791 318 799ZM489 791T482 799T474 817Q474 828
481 835T500 843Q510 843 518 836T526 817Q526 807 518 799T500 791Q489 791 482 799Z" />
<glyph unicode="&#xd7;" glyph-name="multiply" horiz-adv-x="560" d="M294 350L432 212L418 198L280 336L142 198L128 212L266 350L128 488L142 502L280 364L418 502L432 488L294 350Z" />
<glyph unicode="&#xd8;" glyph-name="Oslash" horiz-adv-x="836" d="M317 -3T235 43T106 169T59 350Q59 450 106 530T235 657T418 703Q519 703 601 657T730 531T777 350Q777 250 730 170T601 43T418 -3Q317 -3 235 43ZM513 16T590 59T712 179T757 350Q757 444
713 520T591 640T418 684Q323 684 246 641T124 521T79 350Q79 256 123 180T245 60T418 16Q513 16 590 59ZM714 770H737L122 -70H99L714 770Z" />
<glyph unicode="&#xd9;" glyph-name="Ugrave" horiz-adv-x="794" d="M269 -3T198 72T127 293V700H147V294Q147 156 211 86T397 16Q518 16 582 86T647 294V700H667V293Q667 147 596 72T397 -3Q269 -3 198 72ZM262 867H302L442 757H412L262 867Z" />
<glyph unicode="&#xda;" glyph-name="Uacute" horiz-adv-x="794" d="M269 -3T198 72T127 293V700H147V294Q147 156 211 86T397 16Q518 16 582 86T647 294V700H667V293Q667 147 596 72T397 -3Q269 -3 198 72ZM492 867H532L382 757H352L492 867Z" />
<glyph unicode="&#xdb;" glyph-name="Ucircumflex" horiz-adv-x="794" d="M269 -3T198 72T127 293V700H147V294Q147 156 211 86T397 16Q518 16 582 86T647 294V700H667V293Q667 147 596 72T397 -3Q269 -3 198 72ZM508 757L397 850L286 757H259L381 867H413L535 757H508Z" />
<glyph unicode="&#xdc;" glyph-name="Udieresis" horiz-adv-x="794" d="M269 -3T198 72T127 293V700H147V294Q147 156 211 86T397 16Q518 16 582 86T647 294V700H667V293Q667 147 596 72T397 -3Q269 -3 198 72ZM304 791T297 799T289 817Q289 828 296 835T315 843Q325
843 333 836T341 817Q341 807 333 799T315 791Q304 791 297 799ZM468 791T461 799T453 817Q453 828 460 835T479 843Q489 843 497 836T505 817Q505 807 497 799T479 791Q468 791 461 799Z" />
<glyph unicode="&#xdd;" glyph-name="Yacute" horiz-adv-x="610" d="M315 238V0H295V238L10 700H33L305 259L577 700H600L315 238ZM400 867H440L290 757H260L400 867Z" />
<glyph unicode="&#xde;" glyph-name="Thorn" horiz-adv-x="710" d="M499 600T572 540T645 370Q645 261 572 200T370 139H153V0H133V700H153V600H370Q499 600 572 540ZM494 158T559 213T625 370Q625 471 560 526T372 581H153V158H372Q494 158 559 213Z" />
<glyph unicode="&#xdf;" glyph-name="germandbls" horiz-adv-x="652" d="M494 378T546 328T598 194Q598 134 568 90T486 21T370 -3Q309 -3 264 12L270 31Q315 16 370 16Q461 16 519 63T578 194Q578 277 521 324T371 371H311V390Q409 390 465 438T521 568Q521 638
472 682T336 726Q243 726 189 670T135 507V0H115V508Q115 622 175 683T335 745Q397 745 444 722T516 659T541 568Q541 500 503 453T404 387Q494 378 546 328Z" />
<glyph unicode="&#xe0;" glyph-name="agrave" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169 499T280
520Q370 520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148ZM138 717H178L318 607H288L138 717Z" />
<glyph unicode="&#xe1;" glyph-name="aacute" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169 499T280
520Q370 520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148ZM368 717H408L258 607H228L368 717Z" />
<glyph unicode="&#xe2;" glyph-name="acircumflex" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169
499T280 520Q370 520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148ZM384 607L273 700L162 607H135L257 717H289L411 607H384Z" />
<glyph unicode="&#xe3;" glyph-name="atilde" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169 499T280
520Q370 520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148ZM316 619T301 628T265 657Q249 672 237 680T210 688Q186 688 172 670T156 621H137Q139 660 158 683T210 707Q230 707 245 698T281 669Q297 654 309 646T336
638Q360 638 374 655T390 703H409Q407 665 388 642T336 619Q316 619 301 628Z" />
<glyph unicode="&#xe4;" glyph-name="adieresis" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169
499T280 520Q370 520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148ZM180 641T173 649T165 667Q165 678 172 685T191 693Q201 693 209 686T217 667Q217 657 209 649T191 641Q180 641 173 649ZM344 641T337 649T329
667Q329 678 336 685T355 693Q365 693 373 686T381 667Q381 657 373 649T355 641Q344 641 337 649Z" />
<glyph unicode="&#xe5;" glyph-name="aring" horiz-adv-x="574" d="M370 520T417 474T465 339V0H445V110Q420 57 370 27T248 -3Q162 -3 114 36T65 142Q65 204 108 242T249 281H445V338Q445 419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169 499T280
520Q370 520 417 474ZM392 16T445 148V262H248Q164 262 125 230T85 143Q85 84 128 50T248 16Q392 16 445 148ZM232 597T206 623T180 687Q180 725 206 752T272 780Q311 780 338 753T365 687Q365 650 339 624T272 597Q232 597 206 623ZM304 616T324 636T345 687Q345
717 324 739T272 761Q241 761 221 740T200 687Q200 657 220 637T272 616Q304 616 324 636Z" />
<glyph unicode="&#xe6;" glyph-name="ae" horiz-adv-x="979" d="M465 261V259Q465 189 496 134T581 47T704 16Q757 16 803 36T880 96L894 82Q860 41 810 19T704 -3Q623 -3 558 39T462 160Q447 78 389 38T248 -3Q162 -3 114 36T65 142Q65 203 108 241T249 280H445V338Q445
419 404 460T281 501Q225 501 177 482T93 429L79 443Q116 479 169 499T280 520Q448 520 464 364Q491 435 550 477T685 520Q752 520 807 488T893 397T925 266V261H465ZM625 501T576 473T498 394T465 280H906Q902 343 873 393T794 472T685 501Q625 501 576 473ZM337
16T391 65T445 202V261H248Q164 261 125 229T85 143Q85 84 128 50T248 16Q337 16 391 65Z" />
<glyph unicode="&#xe7;" glyph-name="ccedilla" horiz-adv-x="545" d="M235 -3T177 30T87 123T54 259Q54 335 86 394T177 487T308 520Q365 520 413 499T494 436L480 421Q451 461 406 481T308 501Q241 501 188 471T104 385T74 259Q74 188 104 133T187 47T308 16Q361
16 406 36T480 96L494 81Q462 40 414 19T308 -3Q235 -3 177 30ZM232 -213T201 -186L212 -171Q237 -194 274 -194Q306 -194 326 -178T346 -134Q346 -107 327 -91T275 -74H259L281 5H300L283 -56Q321 -58 343 -79T366 -134Q366 -170 341 -191T275 -213Q232 -213 201
-186Z" />
<glyph unicode="&#xe8;" glyph-name="egrave" horiz-adv-x="587" d="M533 259H73Q73 189 104 134T189 47T312 16Q365 16 411 36T488 96L502 82Q468 41 418 19T312 -3Q238 -3 180 30T88 124T54 259Q54 334 85 393T170 486T293 520Q360 520 415 487T501 396T533
264V259ZM233 501T184 472T106 392T73 278H514Q511 341 481 392T402 472T293 501Q233 501 184 472ZM159 717H199L339 607H309L159 717Z" />
<glyph unicode="&#xe9;" glyph-name="eacute" horiz-adv-x="587" d="M533 259H73Q73 189 104 134T189 47T312 16Q365 16 411 36T488 96L502 82Q468 41 418 19T312 -3Q238 -3 180 30T88 124T54 259Q54 334 85 393T170 486T293 520Q360 520 415 487T501 396T533
264V259ZM233 501T184 472T106 392T73 278H514Q511 341 481 392T402 472T293 501Q233 501 184 472ZM389 717H429L279 607H249L389 717Z" />
<glyph unicode="&#xea;" glyph-name="ecircumflex" horiz-adv-x="587" d="M533 259H73Q73 189 104 134T189 47T312 16Q365 16 411 36T488 96L502 82Q468 41 418 19T312 -3Q238 -3 180 30T88 124T54 259Q54 334 85 393T170 486T293 520Q360 520 415 487T501 396T533
264V259ZM233 501T184 472T106 392T73 278H514Q511 341 481 392T402 472T293 501Q233 501 184 472ZM405 607L294 700L183 607H156L278 717H310L432 607H405Z" />
<glyph unicode="&#xeb;" glyph-name="edieresis" horiz-adv-x="587" d="M533 259H73Q73 189 104 134T189 47T312 16Q365 16 411 36T488 96L502 82Q468 41 418 19T312 -3Q238 -3 180 30T88 124T54 259Q54 334 85 393T170 486T293 520Q360 520 415 487T501 396T533
264V259ZM233 501T184 472T106 392T73 278H514Q511 341 481 392T402 472T293 501Q233 501 184 472ZM201 641T194 649T186 667Q186 678 193 685T212 693Q222 693 230 686T238 667Q238 657 230 649T212 641Q201 641 194 649ZM365 641T358 649T350 667Q350 678 357
685T376 693Q386 693 394 686T402 667Q402 657 394 649T376 641Q365 641 358 649Z" />
<glyph unicode="&#xec;" glyph-name="igrave" horiz-adv-x="250" d="M115 517H135V0H115V517ZM-10 717H30L170 607H140L-10 717Z" />
<glyph unicode="&#xed;" glyph-name="iacute" horiz-adv-x="250" d="M115 517H135V0H115V517ZM220 717H260L110 607H80L220 717Z" />
<glyph unicode="&#xee;" glyph-name="icircumflex" horiz-adv-x="250" d="M115 517H135V0H115V517ZM211 607L125 701L39 607H12L110 717H140L238 607H211Z" />
<glyph unicode="&#xef;" glyph-name="idieresis" horiz-adv-x="250" d="M115 517H135V0H115V517ZM59 641T52 648T44 667Q44 678 51 685T69 693Q79 693 86 686T94 667Q94 656 87 649T69 641Q59 641 52 648ZM171 641T164 648T156 667Q156 678 163 685T181 693Q191
693 198 686T206 667Q206 656 199 649T181 641Q171 641 164 648Z" />
<glyph unicode="&#xf0;" glyph-name="eth" horiz-adv-x="618" d="M498 607T531 531T564 350Q564 186 493 92T286 -3Q218 -3 166 24T84 100T54 214Q54 279 83 327T167 403T294 430Q389 430 454 378T531 233Q544 285 544 352Q544 455 511 528T416 641L148 521L140
540L394 654Q335 684 257 684Q179 684 107 663L102 682Q132 691 173 697T257 703Q348 703 417 664L505 703L513 684L437 650Q498 607 531 531ZM357 16T408 44T486 118T513 214Q513 268 485 313T407 384T294 411Q192 411 133 357T74 214Q74 156 100 111T175 41T286
16Q357 16 408 44Z" />
<glyph unicode="&#xf1;" glyph-name="ntilde" horiz-adv-x="668" d="M449 520T504 465T559 305V0H539V305Q539 400 491 450T353 501Q252 501 194 441T135 281V0H115V517H135V379Q159 445 215 482T352 520Q449 520 504 465ZM378 619T363 628T327 657Q311 672 299
680T272 688Q248 688 234 670T218 621H199Q201 660 220 683T272 707Q292 707 307 698T343 669Q359 654 371 646T398 638Q422 638 436 655T452 703H471Q469 665 450 642T398 619Q378 619 363 628Z" />
<glyph unicode="&#xf2;" glyph-name="ograve" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329 506
384T423 470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47ZM170 717H210L350 607H320L170 717Z" />
<glyph unicode="&#xf3;" glyph-name="oacute" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329 506
384T423 470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47ZM400 717H440L290 607H260L400 717Z" />
<glyph unicode="&#xf4;" glyph-name="ocircumflex" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329
506 384T423 470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47ZM416 607L305 700L194 607H167L289 717H321L443 607H416Z" />
<glyph unicode="&#xf5;" glyph-name="otilde" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329 506
384T423 470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47ZM348 619T333 628T297 657Q281 672 269 680T242 688Q218 688 204 670T188 621H169Q171 660 190 683T242 707Q262 707 277 698T313 669Q329 654 341 646T368 638Q392
638 406 655T422 703H441Q439 665 420 642T368 619Q348 619 333 628Z" />
<glyph unicode="&#xf6;" glyph-name="odieresis" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329
506 384T423 470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47ZM212 641T205 649T197 667Q197 678 204 685T223 693Q233 693 241 686T249 667Q249 657 241 649T223 641Q212 641 205 649ZM376 641T369 649T361 667Q361 678
368 685T387 693Q397 693 405 686T413 667Q413 657 405 649T387 641Q376 641 369 649Z" />
<glyph unicode="&#xf7;" glyph-name="divide" horiz-adv-x="560" d="M270 504T262 512T254 530Q254 541 262 548T280 556Q291 556 298 549T306 530Q306 520 299 512T280 504Q270 504 262 512ZM75 359H485V340H75V359ZM270 144T262 152T254 170Q254 181 262 188T280
196Q291 196 298 189T306 170Q306 160 299 152T280 144Q270 144 262 152Z" />
<glyph unicode="&#xf8;" glyph-name="oslash" horiz-adv-x="610" d="M234 -3T177 30T87 124T54 259Q54 334 86 393T176 486T305 520Q376 520 433 487T523 394T556 259Q556 184 524 124T434 31T305 -3Q234 -3 177 30ZM370 16T423 47T506 133T536 259Q536 329 506
384T423 470T305 501Q240 501 187 471T104 385T74 259Q74 189 104 134T187 47T305 16Q370 16 423 47ZM516 587H539L93 -70H70L516 587Z" />
<glyph unicode="&#xf9;" glyph-name="ugrave" horiz-adv-x="664" d="M549 517V0H529V137Q506 71 452 34T321 -3Q221 -3 165 52T109 212V517H129V212Q129 117 179 67T320 16Q417 16 473 76T529 236V517H549ZM194 717H234L374 607H344L194 717Z" />
<glyph unicode="&#xfa;" glyph-name="uacute" horiz-adv-x="664" d="M549 517V0H529V137Q506 71 452 34T321 -3Q221 -3 165 52T109 212V517H129V212Q129 117 179 67T320 16Q417 16 473 76T529 236V517H549ZM424 717H464L314 607H284L424 717Z" />
<glyph unicode="&#xfb;" glyph-name="ucircumflex" horiz-adv-x="664" d="M549 517V0H529V137Q506 71 452 34T321 -3Q221 -3 165 52T109 212V517H129V212Q129 117 179 67T320 16Q417 16 473 76T529 236V517H549ZM440 607L329 700L218 607H191L313 717H345L467 607H440Z" />
<glyph unicode="&#xfc;" glyph-name="udieresis" horiz-adv-x="664" d="M549 517V0H529V137Q506 71 452 34T321 -3Q221 -3 165 52T109 212V517H129V212Q129 117 179 67T320 16Q417 16 473 76T529 236V517H549ZM236 641T229 649T221 667Q221 678 228 685T247 693Q257
693 265 686T273 667Q273 657 265 649T247 641Q236 641 229 649ZM400 641T393 649T385 667Q385 678 392 685T411 693Q421 693 429 686T437 667Q437 657 429 649T411 641Q400 641 393 649Z" />
<glyph unicode="&#xfd;" glyph-name="yacute" horiz-adv-x="508" d="M502 517L227 -83Q199 -145 164 -171T81 -197Q11 -197 -31 -151L-16 -135Q5 -158 28 -168T82 -178Q122 -178 151 -156T207 -77L243 2L6 517H29L254 23L479 517H502ZM334 717H374L224 607H194L334 717Z" />
<glyph unicode="&#xfe;" glyph-name="thorn" horiz-adv-x="671" d="M436 520T493 487T584 393T617 258Q617 183 584 124T494 31T366 -3Q286 -3 224 40T135 157V-194H115V742H135V359Q161 433 223 476T366 520Q436 520 493 487ZM431 16T484 46T567 132T597 258Q597
328 567 383T484 470T366 501Q301 501 248 470T165 384T135 258Q135 188 165 133T248 47T366 16Q431 16 484 46Z" />
<glyph unicode="&#xff;" glyph-name="ydieresis" horiz-adv-x="508" d="M502 517L227 -83Q199 -145 164 -171T81 -197Q11 -197 -31 -151L-16 -135Q5 -158 28 -168T82 -178Q122 -178 151 -156T207 -77L243 2L6 517H29L254 23L479 517H502ZM146 641T139 649T131
667Q131 678 138 685T157 693Q167 693 175 686T183 667Q183 657 175 649T157 641Q146 641 139 649ZM310 641T303 649T295 667Q295 678 302 685T321 693Q331 693 339 686T347 667Q347 657 339 649T321 641Q310 641 303 649Z" />
<glyph unicode="&#x2013;" glyph-name="endash" horiz-adv-x="500" d="M0 274H500V255H0V274Z" />
<glyph unicode="&#x2014;" glyph-name="emdash" horiz-adv-x="1000" d="M0 274H1000V255H0V274Z" />
<glyph unicode="&#x2018;" glyph-name="quoteleft" horiz-adv-x="182" d="M102 604T109 597T117 579Q117 568 110 561T91 553Q80 553 73 561T65 579Q65 586 69 608L102 742H120L91 605Q102 604 109 597Z" />
<glyph unicode="&#x2019;" glyph-name="quoteright" horiz-adv-x="182" d="M102 745T109 737T117 719Q117 712 113 690L80 556H62L91 693Q80 694 73 701T65 719Q65 730 72 737T91 745Q102 745 109 737Z" />
<glyph unicode="&#x201a;" glyph-name="quotesinglbase" horiz-adv-x="182" d="M102 49T109 41T117 23Q117 16 113 -6L80 -140H62L91 -3Q80 -2 73 5T65 23Q65 34 72 41T91 49Q102 49 109 41Z" />
<glyph unicode="&#x201c;" glyph-name="quotedblleft" horiz-adv-x="312" d="M102 604T109 597T117 579Q117 568 110 561T91 553Q80 553 73 561T65 579Q65 586 69 608L102 742H120L91 605Q102 604 109 597ZM232 604T239 597T247 579Q247 568 240 561T221 553Q210
553 203 561T195 579Q195 586 199 608L232 742H250L221 605Q232 604 239 597Z" />
<glyph unicode="&#x201d;" glyph-name="quotedblright" horiz-adv-x="312" d="M102 745T109 737T117 719Q117 712 113 690L80 556H62L91 693Q80 694 73 701T65 719Q65 730 72 737T91 745Q102 745 109 737ZM232 745T239 737T247 719Q247 712 243 690L210 556H192L221
693Q210 694 203 701T195 719Q195 730 202 737T221 745Q232 745 239 737Z" />
<glyph unicode="&#x201e;" glyph-name="quotedblbase" horiz-adv-x="312" d="M102 49T109 41T117 23Q117 16 113 -6L80 -140H62L91 -3Q80 -2 73 5T65 23Q65 34 72 41T91 49Q102 49 109 41ZM232 49T239 41T247 23Q247 16 243 -6L210 -140H192L221 -3Q210 -2 203
5T195 23Q195 34 202 41T221 49Q232 49 239 41Z" />
<glyph unicode="&#x2022;" glyph-name="bullet" horiz-adv-x="258" d="M111 225T98 238T85 269Q85 287 98 300T129 313Q147 313 160 300T173 269Q173 251 160 238T129 225Q111 225 98 238Z" />
<glyph unicode="&#x2039;" glyph-name="guilsinglleft" horiz-adv-x="273" d="M58 259L205 444H228L82 259L228 74H205L58 259Z" />
<glyph unicode="&#x203a;" glyph-name="guilsinglright" horiz-adv-x="273" d="M45 74L191 259L45 444H68L215 259L68 74H45Z" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@ -1,337 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<defs >
<font id="Montserrat" horiz-adv-x="628" ><font-face
font-family="Montserrat Thin"
units-per-em="1000"
panose-1="0 0 3 0 0 0 0 0 0 0"
ascent="968"
descent="-251"
alphabetic="0" />
<glyph unicode=" " glyph-name="space" horiz-adv-x="250" />
<glyph unicode="!" glyph-name="exclam" horiz-adv-x="242" d="M198 700H220L114 188H100L198 700ZM64 -3T56 5T48 23Q48 34 56 41T74 49Q85 49 92 42T100 23Q100 13 93 5T74 -3Q64 -3 56 5Z" />
<glyph unicode="&quot;" glyph-name="quotedbl" horiz-adv-x="334" d="M169 700H191L139 450H121L169 700ZM319 700H341L289 450H271L319 700Z" />
<glyph unicode="#" glyph-name="numbersign" horiz-adv-x="682" d="M538 471L461 229H610L606 210H455L387 0H366L434 210H195L127 0H106L174 210H26L30 229H180L257 471H109L113 490H264L331 700H352L285 490H524L591 700H612L545 490H693L689 471H538ZM517 471H278L201
229H440L517 471Z" />
<glyph unicode="$" glyph-name="dollar" horiz-adv-x="601" d="M542 652T496 667T396 684L331 358Q396 339 434 323T500 276T527 195Q527 100 453 49T263 -3H258L235 -120H216L240 -2Q171 3 112 29T26 95L42 108Q67 71 123 46T243 17L309 344Q253 360 216 377T155
424T131 503Q131 596 200 648T381 703L404 820H423L400 703Q455 701 505 685T590 641L577 624Q542 652 496 667ZM150 464T171 437T227 394T313 363L377 684Q276 681 213 634T150 505Q150 464 171 437ZM507 237T483 264T423 306T327 338L262 16H264Q373 16 440 63T507
194Q507 237 483 264Z" />
<glyph unicode="%" glyph-name="percent" horiz-adv-x="800" d="M165 328T131 366T97 472Q97 531 119 584T183 669T277 702Q335 702 369 664T403 558Q403 499 381 446T317 361T223 328Q165 328 131 366ZM714 700H738L122 0H98L714 700ZM272 346T308 376T364 455T383
556Q383 616 355 650T276 684Q228 684 192 654T136 575T117 474Q117 414 145 380T224 346Q272 346 308 376ZM501 -3T467 35T433 141Q433 200 455 253T519 338T613 371Q671 371 705 333T739 227Q739 168 717 115T653 30T559 -3Q501 -3 467 35ZM608 15T644 45T700
124T719 225Q719 285 691 319T612 353Q564 353 528 323T472 244T453 143Q453 83 481 49T560 15Q608 15 644 45Z" />
<glyph unicode="&amp;" glyph-name="ampersand" horiz-adv-x="634" d="M544 188T488 121L575 1L560 -10L475 107Q375 -3 223 -3Q137 -3 86 38T35 147Q35 191 57 229T130 307T270 391L263 400Q233 441 219 476T204 545Q204 617 250 660T374 703Q434 703 469 673T505
593Q505 552 486 520T423 457T298 384L477 136Q528 198 564 290L582 286Q544 188 488 121ZM224 485T280 408L286 399Q365 439 407 468T467 526T486 593Q486 633 456 658T374 684Q306 684 265 647T224 547Q224 485 280 408ZM367 14T465 121L281 375Q193 331 144
295T75 224T55 147Q55 87 100 51T224 14Q367 14 465 121Z" />
<glyph unicode="&apos;" glyph-name="quotesingle" horiz-adv-x="184" d="M169 700H191L139 450H121L169 700Z" />
<glyph unicode="(" glyph-name="parenleft" horiz-adv-x="311" d="M125 -137T115 -72T104 55Q104 240 166 428T329 742H349Q283 661 232 546T151 303T122 55Q122 -68 161 -194H144Q125 -137 115 -72Z" />
<glyph unicode=")" glyph-name="parenright" horiz-adv-x="311" d="M99 -113T150 2T231 245T260 493Q260 616 221 742H238Q257 685 267 620T278 493Q278 308 216 120T53 -194H33Q99 -113 150 2Z" />
<glyph unicode="*" glyph-name="asterisk" horiz-adv-x="358" d="M261 571L378 495L367 480L248 558L216 402H198L229 555L82 479L74 495L225 573L106 650L117 665L236 587L266 742H284L254 587L403 665L410 648L261 571Z" />
<glyph unicode="+" glyph-name="plus" horiz-adv-x="560" d="M502 340H306L268 150H248L286 340H91L95 359H290L328 550H348L310 359H506L502 340Z" />
<glyph unicode="," glyph-name="comma" horiz-adv-x="182" d="M55 49T62 42T70 23Q70 13 66 5T61 -6L0 -140H-18L39 -2Q30 -1 24 6T18 23Q18 34 26 41T44 49Q55 49 62 42Z" />
<glyph unicode="-" glyph-name="hyphen" horiz-adv-x="380" d="M68 274H318L314 255H64L68 274Z" />
<glyph unicode="." glyph-name="period" horiz-adv-x="182" d="M34 -3T26 5T18 23Q18 34 26 41T44 49Q55 49 62 42T70 23Q70 13 63 5T44 -3Q34 -3 26 5Z" />
<glyph unicode="/" glyph-name="slash" horiz-adv-x="300" d="M424 842H446L-70 -100H-92L424 842Z" />
<glyph unicode="0" glyph-name="zero" horiz-adv-x="652" d="M178 -3T123 62T67 243Q67 359 109 465T229 637T410 703Q510 703 565 638T621 457Q621 341 579 235T459 63T278 -3Q178 -3 123 62ZM378 16T451 80T564 247T603 458Q603 565 552 624T407 684Q310 684
237 620T124 453T85 242Q85 135 136 76T281 16Q378 16 451 80Z" />
<glyph unicode="1" glyph-name="one" horiz-adv-x="342" d="M297 700L157 0H138L274 681H94L98 700H297Z" />
<glyph unicode="2" glyph-name="two" horiz-adv-x="555" d="M29 19H463L459 0H-9L-6 15L364 321Q446 390 478 440T510 548Q510 612 466 648T331 684Q266 684 209 662T113 599L98 613Q140 656 201 679T332 703Q430 703 480 662T530 549Q530 488 496 433T378 307L29 19Z" />
<glyph unicode="3" glyph-name="three" horiz-adv-x="548" d="M549 685L265 387Q371 386 425 342T480 216Q480 151 447 102T354 25T215 -3Q134 -3 73 24T-15 96L2 109Q26 67 82 42T216 16Q290 16 345 41T430 111T460 216Q460 291 411 329T260 368H232L235 383L519
681H125L129 700H552L549 685Z" />
<glyph unicode="4" glyph-name="four" horiz-adv-x="644" d="M617 208H461L419 0H399L441 208H36L39 223L525 700H552L70 227H444L481 410H501L464 227H621L617 208Z" />
<glyph unicode="5" glyph-name="five" horiz-adv-x="548" d="M216 681L126 397H248Q374 397 434 351T495 220Q495 117 424 57T230 -3Q149 -3 88 24T0 96L17 109Q41 67 97 42T232 16Q346 16 410 70T475 220Q475 297 421 337T245 378H100L201 700H556L552 681H216Z" />
<glyph unicode="6" glyph-name="six" horiz-adv-x="592" d="M308 684T231 621T120 460T86 254V238Q110 322 177 364T326 406Q424 406 485 355T546 215Q546 114 480 56T306 -3Q196 -3 131 64T66 260Q66 371 102 471T221 637T433 703Q528 703 585 668L573 650Q521
684 431 684Q308 684 231 621ZM259 387T208 361T127 289T98 191Q98 147 121 107T192 42T307 16Q407 16 466 69T526 213Q526 296 471 341T325 387Q259 387 208 361Z" />
<glyph unicode="7" glyph-name="seven" horiz-adv-x="570" d="M610 700L607 685L159 0H134L579 681H140L112 540H92L124 700H610Z" />
<glyph unicode="8" glyph-name="eight" horiz-adv-x="624" d="M481 345T518 303T555 201Q555 139 522 93T427 22T283 -3Q169 -3 105 44T41 174Q41 255 98 307T257 370Q198 386 167 423T135 514Q135 601 201 652T379 703Q479 703 539 660T600 541Q600 468 551 421T412
362Q481 345 518 303ZM156 452T208 414T357 375Q460 375 520 419T580 538Q580 605 526 644T377 684Q276 684 216 639T156 518Q156 452 208 414ZM401 16T468 66T536 200Q536 272 476 314T309 356Q193 356 127 307T60 173Q60 100 119 58T285 16Q401 16 468 66Z" />
<glyph unicode="9" glyph-name="nine" horiz-adv-x="592" d="M432 703T497 636T562 440Q562 329 526 229T407 63T195 -3Q100 -3 43 32L55 50Q107 16 197 16Q320 16 397 79T508 240T542 446V462Q518 378 451 336T302 294Q204 294 143 345T82 485Q82 586 148 644T322
703Q432 703 497 636ZM369 313T420 339T501 411T530 509Q530 553 507 593T436 658T321 684Q221 684 162 631T102 487Q102 404 157 359T303 313Q369 313 420 339Z" />
<glyph unicode=":" glyph-name="colon" horiz-adv-x="182" d="M129 468T121 476T113 494Q113 505 121 512T139 520Q150 520 157 513T165 494Q165 484 158 476T139 468Q129 468 121 476ZM34 -3T26 5T18 23Q18 34 26 41T44 49Q55 49 62 42T70 23Q70 13 63 5T44 -3Q34
-3 26 5Z" />
<glyph unicode=";" glyph-name="semicolon" horiz-adv-x="182" d="M129 468T121 476T113 494Q113 505 121 512T139 520Q150 520 157 513T165 494Q165 484 158 476T139 468Q129 468 121 476ZM55 49T62 42T70 23Q70 13 66 5T61 -6L0 -140H-18L39 -2Q30 -1 24 6T18
23Q18 34 26 41T44 49Q55 49 62 42Z" />
<glyph unicode="&lt;" glyph-name="less" horiz-adv-x="560" d="M533 509L114 349L470 188L466 168L90 339L94 361L538 532L533 509Z" />
<glyph unicode="=" glyph-name="equal" horiz-adv-x="560" d="M118 469H528L524 450H114L118 469ZM74 250H484L480 231H70L74 250Z" />
<glyph unicode="&gt;" glyph-name="greater" horiz-adv-x="560" d="M506 361L502 339L58 168L63 191L482 351L126 512L130 532L506 361Z" />
<glyph unicode="?" glyph-name="question" horiz-adv-x="554" d="M244 233T265 266T313 323T379 374Q421 405 445 427T485 481T502 558Q502 618 458 651T333 684Q257 684 201 663T102 599L89 614Q180 703 333 703Q423 703 472 666T521 558Q521 509 504 473T461
414T390 358Q350 329 327 309T283 258T256 188H236Q244 233 265 266ZM203 -3T195 5T187 23Q187 34 195 41T213 49Q224 49 231 42T239 23Q239 13 232 5T213 -3Q203 -3 195 5Z" />
<glyph unicode="@" glyph-name="at" horiz-adv-x="1032" d="M709 703T799 659T936 533T983 343Q983 253 955 173T881 45T783 -3Q748 -3 727 16T706 68Q706 75 708 89L717 135Q680 71 617 34T474 -3Q373 -3 314 53T254 207Q254 296 291 367T395 479T546 520Q638
520 693 476T759 349L793 517H813L730 99Q727 84 727 71Q727 16 785 16Q831 16 872 62T938 185T963 345Q963 447 920 523T790 641T580 684Q428 684 312 614T131 425T67 165Q67 63 110 -14T236 -134T436 -177Q492 -177 543 -165T633 -131L638 -151Q596 -173 543
-185T432 -197Q313 -197 226 -152T93 -24T47 166Q47 310 112 433T299 629T582 703Q709 703 799 659ZM553 16T614 54T711 159T746 309Q746 400 693 450T543 501Q467 501 406 463T309 358T274 208Q274 117 327 67T477 16Q553 16 614 54Z" />
<glyph unicode="A" glyph-name="A" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545Z" />
<glyph unicode="B" glyph-name="B" horiz-adv-x="748" d="M596 349T634 313T672 214Q672 111 597 56T382 0H81L221 700H498Q593 700 647 664T701 559Q701 478 653 427T526 358Q596 349 634 313ZM174 365H435Q545 365 613 414T681 556Q681 618 634 649T498 681H237L174
365ZM514 19T583 69T652 212Q652 283 604 314T455 346H170L105 19H386Q514 19 583 69Z" />
<glyph unicode="C" glyph-name="C" horiz-adv-x="711" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T269 645T492 703Q570 703 631 680T727 615L713 602Q640 684 490 684Q371 684 281 630T141 483T91 280Q91 159 167 88T388 16Q540 16 632 102L644 86Q600
45 532 21T386 -3Q286 -3 215 32Z" />
<glyph unicode="D" glyph-name="D" horiz-adv-x="826" d="M221 700H472Q575 700 647 665T756 567T793 420Q793 299 740 204T587 54T357 0H81L221 700ZM359 19Q483 19 577 70T722 212T773 420Q773 541 696 611T470 681H237L105 19H359Z" />
<glyph unicode="E" glyph-name="E" horiz-adv-x="668" d="M237 681L174 365H560L556 346H170L105 19H551L547 0H81L221 700H672L668 681H237Z" />
<glyph unicode="F" glyph-name="F" horiz-adv-x="629" d="M237 681L170 345H556L552 326H166L101 0H81L221 700H672L668 681H237Z" />
<glyph unicode="G" glyph-name="G" horiz-adv-x="774" d="M572 703T634 680T732 614L718 601Q646 684 490 684Q371 684 281 630T141 483T91 280Q91 159 167 88T388 16Q513 16 611 96L660 343H679L628 87Q582 45 520 21T386 -3Q286 -3 215 32T108 131T71 280Q71
393 122 490T269 645T492 703Q572 703 634 680Z" />
<glyph unicode="H" glyph-name="H" horiz-adv-x="816" d="M771 700L631 0H611L680 346H170L101 0H81L221 700H241L174 365H684L751 700H771Z" />
<glyph unicode="I" glyph-name="I" horiz-adv-x="286" d="M221 700H241L101 0H81L221 700Z" />
<glyph unicode="J" glyph-name="J" horiz-adv-x="477" d="M79 -3T34 24T-30 96L-12 106Q7 64 46 40T140 16Q212 16 254 57T317 196L414 681H152L156 700H438L336 190Q316 87 268 42T137 -3Q79 -3 34 24Z" />
<glyph unicode="K" glyph-name="K" horiz-adv-x="693" d="M363 378L625 0H601L348 365L138 187L101 0H81L221 700H241L144 217L712 700H742L363 378Z" />
<glyph unicode="L" glyph-name="L" horiz-adv-x="580" d="M221 700H241L105 19H522L518 0H81L221 700Z" />
<glyph unicode="M" glyph-name="M" horiz-adv-x="956" d="M911 700L771 0H751L881 652L458 99H446L232 658L101 0H81L221 700H238L456 128L892 700H911Z" />
<glyph unicode="N" glyph-name="N" horiz-adv-x="816" d="M771 700L631 0H614L234 667L101 0H81L221 700H238L618 33L751 700H771Z" />
<glyph unicode="O" glyph-name="O" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782 541 706 612T485
684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70Z" />
<glyph unicode="P" glyph-name="P" horiz-adv-x="710" d="M567 700T628 652T690 514Q690 381 606 311T373 240H149L101 0H81L221 700H456Q567 700 628 652ZM515 259T592 324T670 514Q670 594 615 637T457 681H237L153 259H372Q515 259 592 324Z" />
<glyph unicode="Q" glyph-name="Q" horiz-adv-x="836" d="M676 -105T731 -35L745 -48Q714 -85 672 -104T584 -124Q525 -124 476 -94T380 -3Q282 -2 213 33T107 132T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 311 754 216T617
62T409 -2Q484 -105 585 -105Q676 -105 731 -35ZM91 159T167 88T388 16Q504 16 594 70T733 217T782 420Q782 541 706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88Z" />
<glyph unicode="R" glyph-name="R" horiz-adv-x="716" d="M690 402T631 335T463 248L603 0H580L442 244Q413 240 373 240H149L101 0H81L221 700H456Q567 700 628 652T690 514Q690 402 631 335ZM515 259T592 324T670 514Q670 594 615 637T457 681H237L153 259H372Q515
259 592 324Z" />
<glyph unicode="S" glyph-name="S" horiz-adv-x="601" d="M189 -3T122 25T26 95L42 108Q70 68 133 42T264 16Q373 16 440 63T507 194Q507 237 483 264T423 306T326 338Q262 357 224 373T158 421T131 503Q131 598 203 650T388 703Q446 703 500 687T590 641L577
624Q540 653 492 668T388 684Q282 684 216 636T150 505Q150 461 174 433T235 390T333 357Q398 338 436 322T500 275T527 195Q527 100 453 49T263 -3Q189 -3 122 25Z" />
<glyph unicode="T" glyph-name="T" horiz-adv-x="548" d="M348 681H88L92 700H632L628 681H368L232 0H212L348 681Z" />
<glyph unicode="U" glyph-name="U" horiz-adv-x="794" d="M248 -3T187 53T126 213Q126 254 134 293L215 700H235L154 295Q145 252 145 214Q145 118 200 67T360 16Q480 16 553 84T654 294L735 700H755L674 293Q615 -3 360 -3Q248 -3 187 53Z" />
<glyph unicode="V" glyph-name="V" horiz-adv-x="670" d="M748 700L293 0H273L98 700H119L287 27L724 700H748Z" />
<glyph unicode="W" glyph-name="W" horiz-adv-x="1080" d="M1123 700L743 0H723L622 670L253 0H233L133 700H153L248 30L617 700H637L738 31L1101 700H1123Z" />
<glyph unicode="X" glyph-name="X" horiz-adv-x="621" d="M342 362L544 0H523L330 348L-3 0H-27L320 365L133 700H154L333 378L640 700H664L342 362Z" />
<glyph unicode="Y" glyph-name="Y" horiz-adv-x="610" d="M310 235L263 0H243L291 238L98 700H120L304 258L663 700H688L310 235Z" />
<glyph unicode="Z" glyph-name="Z" horiz-adv-x="639" d="M675 685L32 19H552L548 0H-2L1 15L643 681H139L143 700H678L675 685Z" />
<glyph unicode="[" glyph-name="bracketleft" horiz-adv-x="288" d="M229 742H359L355 723H245L66 -175H176L172 -194H42L229 742Z" />
<glyph unicode="\" glyph-name="backslash" horiz-adv-x="300" d="M229 -100L86 842H105L248 -100H229Z" />
<glyph unicode="]" glyph-name="bracketright" horiz-adv-x="288" d="M-64 -194L-60 -175H50L229 723H119L123 742H253L66 -194H-64Z" />
<glyph unicode="^" glyph-name="asciicircum" horiz-adv-x="562" d="M419 145L337 532L99 145H76L329 555H351L440 145H419Z" />
<glyph unicode="_" glyph-name="underscore" horiz-adv-x="500" d="M-51 0H449L445 -19H-55L-51 0Z" />
<glyph unicode="`" glyph-name="grave" horiz-adv-x="600" d="M256 717H296L414 607H384L256 717Z" />
<glyph unicode="a" glyph-name="a" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400 488 450T338
501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54Z" />
<glyph unicode="b" glyph-name="b" horiz-adv-x="671" d="M503 520T562 464T622 310Q622 221 585 150T481 38T330 -3Q238 -3 183 41T117 168L83 0H63L211 742H231L159 382Q196 447 259 483T402 520Q503 520 562 464ZM409 16T470 54T567 159T602 309Q602 400 549
450T399 501Q323 501 262 463T165 358T130 208Q130 117 183 67T333 16Q409 16 470 54Z" />
<glyph unicode="c" glyph-name="c" horiz-adv-x="545" d="M169 -3T109 53T49 207Q49 296 86 367T191 479T342 520Q407 520 454 498T527 433L512 421Q460 501 341 501Q263 501 201 463T104 358T69 208Q69 116 123 66T277 16Q332 16 380 36T460 94L472 80Q440 41
388 19T274 -3Q169 -3 109 53Z" />
<glyph unicode="d" glyph-name="d" horiz-adv-x="671" d="M653 742L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L633 742H653ZM348 16T409 54T506 159T541 309Q541 400 488 450T338
501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54Z" />
<glyph unicode="e" glyph-name="e" horiz-adv-x="589" d="M72 259Q69 235 69 210Q69 116 123 66T279 16Q337 16 386 36T467 93L479 80Q447 42 394 20T278 -3Q170 -3 110 52T50 210Q50 297 86 368T185 479T326 520Q424 520 480 464T537 310Q537 284 532 259H72ZM232
501T164 440T75 278H516Q518 291 518 316Q518 404 466 452T326 501Q232 501 164 440Z" />
<glyph unicode="f" glyph-name="f" horiz-adv-x="311" d="M371 745T396 736T437 708L423 695Q394 726 341 726Q287 726 256 698T213 609L195 517H369L366 498H191L91 0H71L171 498H71L74 517H174L194 615Q207 679 244 712T342 745Q371 745 396 736Z" />
<glyph unicode="g" glyph-name="g" horiz-adv-x="677" d="M615 517L521 46Q496 -82 428 -139T237 -197Q167 -197 111 -175T21 -111L39 -97Q70 -137 121 -157T238 -178Q350 -178 414 -125T501 43L524 158Q486 92 421 55T274 17Q171 17 111 71T51 219Q51 304 89
373T194 481T345 520Q439 520 495 475T562 349L595 517H615ZM353 36T415 72T513 173T548 317Q548 405 494 453T343 501Q266 501 204 465T106 364T71 220Q71 132 125 84T276 36Q353 36 415 72Z" />
<glyph unicode="h" glyph-name="h" horiz-adv-x="668" d="M482 520T528 477T574 360Q574 334 568 305L507 0H487L548 305Q554 334 554 358Q554 426 513 463T391 501Q292 501 227 446T140 287L83 0H63L211 742H231L161 391Q234 520 393 520Q482 520 528 477Z" />
<glyph unicode="i" glyph-name="i" horiz-adv-x="250" d="M166 517H186L83 0H63L166 517ZM198 660T191 667T184 684Q184 695 192 703T212 712Q222 712 229 705T236 688Q236 677 228 669T208 660Q198 660 191 667Z" />
<glyph unicode="j" glyph-name="j" horiz-adv-x="255" d="M-100 -197T-126 -188T-169 -161L-154 -146Q-120 -178 -68 -178Q-18 -178 12 -151T55 -63L171 517H191L74 -69Q49 -197 -70 -197Q-100 -197 -126 -188ZM203 660T196 667T189 684Q189 695 197 703T217 712Q227
712 234 705T241 688Q241 677 233 669T213 660Q203 660 196 667Z" />
<glyph unicode="k" glyph-name="k" horiz-adv-x="557" d="M312 311L500 0H476L296 298L115 159L83 0H63L211 742H231L120 187L548 517H580L312 311Z" />
<glyph unicode="l" glyph-name="l" horiz-adv-x="250" d="M211 742H231L83 0H63L211 742Z" />
<glyph unicode="m" glyph-name="m" horiz-adv-x="1068" d="M885 520T929 478T974 361Q974 335 968 305L907 0H887L948 305Q954 335 954 360Q954 427 914 464T797 501Q704 501 640 450T556 304L495 0H475L536 305Q542 335 542 360Q542 427 502 464T385 501Q290
501 226 446T140 287L83 0H63L166 517H186L161 391Q235 520 387 520Q468 520 512 483T561 379Q598 449 659 484T798 520Q885 520 929 478Z" />
<glyph unicode="n" glyph-name="n" horiz-adv-x="668" d="M482 520T528 477T574 360Q574 334 568 305L507 0H487L548 305Q554 334 554 358Q554 426 513 463T391 501Q292 501 227 446T140 287L83 0H63L166 517H186L161 391Q234 520 393 520Q482 520 528 477Z" />
<glyph unicode="o" glyph-name="o" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338 501Q262 501 201
463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54Z" />
<glyph unicode="p" glyph-name="p" horiz-adv-x="671" d="M503 520T562 464T622 310Q622 221 585 150T481 38T330 -3Q238 -3 183 41T117 168L44 -194H24L166 517H186L159 382Q196 447 259 483T402 520Q503 520 562 464ZM409 16T470 54T567 159T602 309Q602 400
549 450T399 501Q323 501 262 463T165 358T130 208Q130 117 183 67T333 16Q409 16 470 54Z" />
<glyph unicode="q" glyph-name="q" horiz-adv-x="671" d="M608 517L466 -194H446L512 134Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400 488 450T338
501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54Z" />
<glyph unicode="r" glyph-name="r" horiz-adv-x="383" d="M230 520T390 520L386 500H377Q282 500 221 442T137 270L83 0H63L166 517H186L159 384Q230 520 390 520Z" />
<glyph unicode="s" glyph-name="s" horiz-adv-x="463" d="M131 -3T78 16T-3 66L12 82Q41 51 89 34T190 16Q279 16 330 50T381 144Q381 178 362 198T314 227T235 248Q183 259 151 270T96 305T74 371Q74 438 130 479T278 520Q326 520 371 506T442 467L428 452Q401
476 361 488T277 501Q194 501 144 466T94 372Q94 337 114 317T163 287T241 267Q294 256 325 245T379 210T401 145Q401 76 344 37T189 -3Q131 -3 78 16Z" />
<glyph unicode="t" glyph-name="t" horiz-adv-x="388" d="M119 139Q114 112 114 96Q114 16 202 16Q253 16 293 48L304 34Q284 16 256 7T200 -3Q148 -3 121 22T94 95Q94 115 98 134L171 498H71L74 517H174L197 630H217L194 517H369L366 498H191L119 139Z" />
<glyph unicode="u" glyph-name="u" horiz-adv-x="664" d="M601 517L498 0H478L503 126Q430 -3 273 -3Q185 -3 140 40T94 157Q94 184 100 212L161 517H181L120 212Q114 184 114 158Q114 90 155 53T275 16Q373 16 438 71T524 230L581 517H601Z" />
<glyph unicode="v" glyph-name="v" horiz-adv-x="508" d="M554 517L213 0H193L58 517H79L207 23L530 517H554Z" />
<glyph unicode="w" glyph-name="w" horiz-adv-x="835" d="M880 517L586 0H568L464 488L184 0H166L59 517H78L178 23L460 517H477L581 24L858 517H880Z" />
<glyph unicode="x" glyph-name="x" horiz-adv-x="498" d="M261 265L418 0H394L248 251L3 0H-24L238 267L91 517H114L252 282L480 517H506L261 265Z" />
<glyph unicode="y" glyph-name="y" horiz-adv-x="508" d="M554 517L155 -90Q115 -150 80 -173T-3 -197Q-37 -197 -66 -185T-112 -151L-96 -136Q-63 -178 0 -178Q38 -178 70 -157T137 -81L192 3L58 517H79L207 23L530 517H554Z" />
<glyph unicode="z" glyph-name="z" horiz-adv-x="491" d="M486 502L29 19H395L391 0H-6L-3 15L454 498H99L102 517H489L486 502Z" />
<glyph unicode="{" glyph-name="braceleft" horiz-adv-x="300" d="M371 742L367 723H335Q296 723 273 704T243 650L180 336Q175 308 165 294T136 273Q157 263 157 233Q157 220 155 212L96 -82Q93 -99 93 -113Q93 -175 156 -175H188L184 -194H159Q119 -194 96 -175T72
-115Q72 -106 76 -82L135 212Q137 226 137 231Q137 265 101 265H66L70 284H105Q130 284 142 296T160 336L223 650Q232 696 262 719T346 742H371Z" />
<glyph unicode="|" glyph-name="bar" horiz-adv-x="286" d="M230 742H250L63 -194H43L230 742Z" />
<glyph unicode="}" glyph-name="braceright" horiz-adv-x="300" d="M240 283L236 264H201Q176 264 164 252T146 212L83 -102Q74 -148 44 -171T-40 -194H-65L-61 -175H-29Q10 -175 33 -156T63 -102L126 212Q132 242 142 256T170 275Q149 286 149 315Q149 328 151
336L210 630Q213 647 213 661Q213 723 150 723H118L122 742H147Q187 742 210 723T234 663Q234 654 230 630L171 336Q169 322 169 317Q169 283 205 283H240Z" />
<glyph unicode="~" glyph-name="asciitilde" horiz-adv-x="560" d="M357 286T336 301T289 345Q267 370 249 383T205 396Q164 396 135 367T94 289H75Q89 348 123 381T206 414Q239 414 260 399T307 355Q329 330 347 317T391 304Q432 304 461 333T502 411H521Q507
352 473 319T390 286Q357 286 336 301Z" />
<glyph unicode="&#xa0;" glyph-name="uni00A0" horiz-adv-x="250" />
<glyph unicode="&#xa1;" glyph-name="exclamdown" horiz-adv-x="242" d="M158 468T150 476T142 494Q142 505 150 512T168 520Q179 520 186 513T194 494Q194 484 187 476T168 468Q158 468 150 476ZM128 329H142L49 -154H27L128 329Z" />
<glyph unicode="&#xa2;" glyph-name="cent" horiz-adv-x="545" d="M420 516T462 494T527 433L512 421Q464 495 360 500L263 16H277Q332 16 380 36T460 94L472 80Q440 41 388 19T274 -3H259L236 -120H217L241 -1Q151 8 100 63T49 207Q49 296 86 367T191 479T342
520H345L368 637H387L364 519Q420 516 462 494ZM69 124T114 75T244 17L341 501Q263 501 201 463T104 358T69 208Q69 124 114 75Z" />
<glyph unicode="&#xa3;" glyph-name="sterling" horiz-adv-x="618" d="M255 684T214 479L190 359H489L485 341H186L122 19H542L538 0H-22L-18 19H102L166 341H46L50 359H170L194 482Q216 592 289 647T478 703Q540 703 591 688T674 642L659 626Q598 684 478 684Q255
684 214 479Z" />
<glyph unicode="&#xa4;" glyph-name="currency" horiz-adv-x="700" d="M644 263T623 214T564 129L672 20L658 6L549 115Q511 82 463 64T361 46Q308 46 261 64T174 116L64 6L50 20L159 130Q122 167 102 215T81 316Q81 370 101 418T159 505L50 615L64 629L174 519Q213
552 260 570T361 589Q414 589 462 571T549 520L658 629L672 615L564 506Q602 468 623 419T644 316Q644 263 623 214ZM101 249T136 192T231 100T361 66Q432 66 492 100T588 191T624 316Q624 384 589 442T493 535T361 569Q291 569 231 535T136 443T101 316Q101 249
136 192Z" />
<glyph unicode="&#xa5;" glyph-name="yen" horiz-adv-x="670" d="M370 313H596L592 295H353L352 294L328 175H568L564 157H325L293 0H273L305 157H64L68 175H308L332 295H92L96 313H325L98 700H120L346 313L724 700H748L370 313Z" />
<glyph unicode="&#xa6;" glyph-name="brokenbar" horiz-adv-x="286" d="M230 742H250L180 392H160L230 742ZM113 156H133L63 -194H43L113 156Z" />
<glyph unicode="&#xa7;" glyph-name="section" horiz-adv-x="471" d="M281 684T238 666T171 617T147 547Q147 511 165 490T212 457T286 433Q336 420 366 407T417 369T438 300Q438 245 403 206T306 152Q364 120 364 55Q364 9 338 -27T264 -83T151 -103Q94 -103
49 -85T-26 -34L-11 -18Q52 -84 152 -84Q240 -84 292 -46T344 54Q344 89 325 110T279 143T205 169Q155 183 125 196T74 234T53 301Q53 353 88 392T186 448Q127 480 127 546Q127 590 153 626T228 682T339 703Q391 703 438 689T511 650L497 635Q470 659 428 671T338
684Q281 684 238 666ZM418 335T399 357T353 391T278 415Q268 418 247 424T211 436Q147 425 110 389T73 302Q73 267 92 246T139 212T213 187Q261 173 282 164Q346 175 382 211T418 299Q418 335 399 357Z" />
<glyph unicode="&#xa8;" glyph-name="dieresis" horiz-adv-x="600" d="M288 641T281 648T273 665Q273 676 281 684T300 693Q310 693 317 686T325 669Q325 658 317 650T298 641Q288 641 281 648ZM452 641T445 648T437 665Q437 676 445 684T464 693Q474 693 481
686T489 669Q489 658 481 650T462 641Q452 641 445 648Z" />
<glyph unicode="&#xa9;" glyph-name="copyright" horiz-adv-x="824" d="M331 -3T251 44T124 172T77 350Q77 447 123 528T251 656T431 703Q530 703 610 657T737 531T783 352Q783 254 736 173T608 44T429 -3Q331 -3 251 44ZM522 16T598 60T719 182T764 352Q764 445
721 521T601 640T431 684Q338 684 261 640T140 519T96 350Q96 258 140 182T260 61T429 16Q522 16 598 60ZM379 139T332 166T259 241T232 350Q232 411 258 459T332 534T437 561Q483 561 522 544T588 493L573 478Q549 510 514 526T436 542Q383 542 342 518T276 450T252
350Q252 294 276 251T341 183T436 158Q478 158 513 174T573 222L588 207Q561 174 522 157T437 139Q379 139 332 166Z" />
<glyph unicode="&#xaa;" glyph-name="ordfeminine" horiz-adv-x="394" d="M332 744T360 722T389 657Q389 644 386 629L347 434H327L339 493Q317 464 283 448T205 432Q155 432 128 451T100 506Q100 551 134 576T228 602H360L366 630Q369 645 369 657Q369 726 277
726Q244 726 211 716T154 685L144 700Q169 720 205 732T279 744Q332 744 360 722ZM295 448T344 522L357 587H225Q176 587 148 566T119 508Q119 479 141 464T207 448Q295 448 344 522Z" />
<glyph unicode="&#xab;" glyph-name="guillemotleft" horiz-adv-x="423" d="M81 258L190 74H168L58 259L242 444H266L81 258ZM231 258L340 74H318L208 259L392 444H416L231 258Z" />
<glyph unicode="&#xac;" glyph-name="logicalnot" horiz-adv-x="560" d="M466 159H446L482 340H91L95 359H506L466 159Z" />
<glyph unicode="&#xad;" glyph-name="uni00AD" horiz-adv-x="380" d="M68 274H318L314 255H64L68 274Z" />
<glyph unicode="&#xae;" glyph-name="registered" horiz-adv-x="824" d="M530 703T610 657T737 531T783 352Q783 254 736 173T608 44T429 -3Q331 -3 251 44T124 172T77 350Q77 447 123 528T251 656T431 703Q530 703 610 657ZM522 16T598 60T719 182T764 352Q764
445 721 521T601 640T431 684Q338 684 261 640T140 519T96 350Q96 258 140 182T260 61T429 16Q522 16 598 60ZM604 377T578 344T503 298L604 142H580L482 294Q462 292 451 292H321V142H301V558H451Q521 558 562 522T604 425Q604 377 578 344ZM513 311T548 341T584
425Q584 479 549 509T449 539H320V311H449Q513 311 548 341Z" />
<glyph unicode="&#xaf;" glyph-name="overscore" horiz-adv-x="600" d="M246 672H518L514 652H242L246 672Z" />
<glyph unicode="&#xb0;" glyph-name="degree" horiz-adv-x="420" d="M228 403T194 423T139 477T119 553Q119 594 139 628T193 683T269 703Q310 703 344 683T399 629T419 553Q419 512 399 478T345 423T269 403Q228 403 194 423ZM305 421T335 438T382 486T400 553Q400
589 383 619T335 667T269 685Q233 685 203 668T156 620T138 553Q138 517 155 487T203 439T269 421Q305 421 335 438Z" />
<glyph unicode="&#xb1;" glyph-name="plusminus" horiz-adv-x="560" d="M506 359L502 340H306L268 150H248L286 340H91L95 359H290L328 550H348L310 359H506ZM27 19H437L433 0H23L27 19Z" />
<glyph unicode="&#xb2;" glyph-name="uni00B2" horiz-adv-x="430" d="M103 345H385L381 327H65L68 341L299 511Q360 557 381 586T402 647Q402 685 372 705T285 726Q192 726 136 676L125 690Q154 717 195 730T286 744Q351 744 386 718T421 647Q421 611 398 579T313
500L103 345Z" />
<glyph unicode="&#xb3;" glyph-name="uni00B3" horiz-adv-x="430" d="M437 728L256 558H263Q328 558 363 531T399 456Q399 394 352 360T222 325Q169 325 127 341T64 383L78 396Q99 372 136 358T223 343Q297 343 338 372T380 456Q380 496 351 518T263 541H226L229
556L408 724H137L141 742H440L437 728Z" />
<glyph unicode="&#xb4;" glyph-name="acute" horiz-adv-x="600" d="M475 717H517L355 607H323L475 717Z" />
<glyph unicode="&#xb5;" glyph-name="uni00B5" horiz-adv-x="670" d="M607 517L504 0H484L509 126Q436 -3 279 -3Q210 -3 166 25T106 109L45 -194H25L167 517H187L126 212Q120 184 120 158Q120 90 161 53T281 16Q379 16 444 71T530 230L587 517H607Z" />
<glyph unicode="&#xb6;" glyph-name="paragraph" horiz-adv-x="600" d="M257 419Q181 419 134 455T87 558Q87 647 151 694T321 742H563L395 -100H375L539 723H337L173 -100H153L257 419Z" />
<glyph unicode="&#xb7;" glyph-name="middot" horiz-adv-x="222" d="M102 238T94 246T86 264Q86 275 94 282T112 290Q123 290 130 283T138 264Q138 254 131 246T112 238Q102 238 94 246Z" />
<glyph unicode="&#xb8;" glyph-name="cedilla" horiz-adv-x="600" d="M149 -213T121 -186L135 -171Q160 -194 200 -194Q235 -194 256 -175T277 -124Q277 -101 261 -88T215 -74H201L239 5H258L229 -56Q261 -59 279 -77T298 -124Q298 -162 270 -187T199 -213Q149
-213 121 -186Z" />
<glyph unicode="&#xb9;" glyph-name="uni00B9" horiz-adv-x="430" d="M379 345L375 327H103L107 345H240L315 724H189L193 742H338L259 345H379Z" />
<glyph unicode="&#xba;" glyph-name="ordmasculine" horiz-adv-x="407" d="M182 432T143 468T104 564Q104 614 128 655T195 720T292 744Q356 744 395 708T434 612Q434 562 410 521T343 456T247 432Q182 432 143 468ZM296 450T334 472T393 531T415 612Q415 663
381 694T290 726Q242 726 204 704T145 645T123 564Q123 512 158 481T249 450Q296 450 334 472Z" />
<glyph unicode="&#xbb;" glyph-name="guillemotright" horiz-adv-x="423" d="M215 259L31 74H7L192 260L83 444H105L215 259ZM365 259L181 74H157L342 260L233 444H255L365 259Z" />
<glyph unicode="&#xbc;" glyph-name="onequarter" horiz-adv-x="1020" d="M371 303L367 285H95L99 303H232L307 682H181L185 700H330L251 303H371ZM823 700H848L233 0H208L823 700ZM956 120H855L831 0H812L836 120H598L601 134L871 415H896L629 138H840L861 243H880L859
138H960L956 120Z" />
<glyph unicode="&#xbd;" glyph-name="onehalf" horiz-adv-x="1020" d="M371 303L367 285H95L99 303H232L307 682H181L185 700H330L251 303H371ZM823 700H848L233 0H208L823 700ZM628 18H910L906 0H590L593 14L824 184Q885 230 906 259T927 320Q927 358 897 378T810
399Q717 399 661 349L650 363Q679 390 720 403T811 417Q876 417 911 391T946 320Q946 284 923 252T838 173L628 18Z" />
<glyph unicode="&#xbe;" glyph-name="threequarters" horiz-adv-x="1020" d="M429 686L248 516H255Q320 516 355 489T391 414Q391 352 344 318T214 283Q161 283 119 299T56 341L70 354Q91 330 128 316T215 301Q289 301 330 330T372 414Q372 454 343 476T255 499H218L221
514L400 682H129L133 700H432L429 686ZM823 700H848L233 0H208L823 700ZM956 120H855L831 0H812L836 120H598L601 134L871 415H896L629 138H840L861 243H880L859 138H960L956 120Z" />
<glyph unicode="&#xbf;" glyph-name="questiondown" horiz-adv-x="554" d="M331 468T323 476T315 494Q315 505 323 512T341 520Q352 520 359 513T367 494Q367 484 360 476T341 468Q331 468 323 476ZM136 -157T87 -120T38 -12Q38 34 56 68T101 126T172 180Q229
220 259 251T298 329H318Q311 290 292 261T248 212T183 165Q140 136 116 115T74 62T57 -12Q57 -72 101 -105T226 -138Q302 -138 358 -117T457 -53L470 -68Q379 -157 226 -157Q136 -157 87 -120Z" />
<glyph unicode="&#xc0;" glyph-name="Agrave" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545ZM330 867H370L488 757H458L330 867Z" />
<glyph unicode="&#xc1;" glyph-name="Aacute" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545ZM549 867H591L429 757H397L549 867Z" />
<glyph unicode="&#xc2;" glyph-name="Acircumflex" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545ZM556 757L454 850L334 757H305L439 867H471L581 757H556Z" />
<glyph unicode="&#xc3;" glyph-name="Atilde" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545ZM496 769T481 778T447 806Q431 822 419 830T391 838Q368 838 352 820T331 771H312Q317 810 339 833T392
857Q413 857 428 848T461 820Q478 804 490 796T517 788Q540 788 556 806T578 853H597Q591 815 570 792T517 769Q496 769 481 778Z" />
<glyph unicode="&#xc4;" glyph-name="Adieresis" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545ZM362 791T355 798T347 815Q347 826 355 834T374 843Q384 843 391 836T399 819Q399 808 391 800T372
791Q362 791 355 798ZM526 791T519 798T511 815Q511 826 519 834T538 843Q548 843 555 836T563 819Q563 808 555 800T536 791Q526 791 519 798Z" />
<glyph unicode="&#xc5;" glyph-name="Aring" horiz-adv-x="688" d="M550 211H121L-19 0H-43L422 700H442L627 0H606L550 211ZM545 230L429 674L134 230H545ZM427 780T401 806T375 870Q375 908 401 935T467 963Q506 963 533 936T560 870Q560 833 534 807T467 780Q427
780 401 806ZM499 799T519 819T540 870Q540 900 519 922T467 944Q436 944 416 923T395 870Q395 840 415 820T467 799Q499 799 519 819Z" />
<glyph unicode="&#xc6;" glyph-name="AE" horiz-adv-x="1005" d="M574 681L511 365H897L893 346H507L442 19H888L884 0H418L460 211H158L-18 0H-43L540 700H1009L1005 681H574ZM464 230L554 681H550L174 230H464Z" />
<glyph unicode="&#xc7;" glyph-name="Ccedilla" horiz-adv-x="711" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T269 645T492 703Q570 703 631 680T727 615L713 602Q640 684 490 684Q371 684 281 630T141 483T91 280Q91 159 167 88T388 16Q540 16 632 102L644
86Q600 45 532 21T386 -3Q286 -3 215 32ZM267 -213T239 -186L253 -171Q278 -194 318 -194Q353 -194 374 -175T395 -124Q395 -101 379 -88T333 -74H319L357 5H376L347 -56Q379 -59 397 -77T416 -124Q416 -162 388 -187T317 -213Q267 -213 239 -186Z" />
<glyph unicode="&#xc8;" glyph-name="Egrave" horiz-adv-x="668" d="M237 681L174 365H560L556 346H170L105 19H551L547 0H81L221 700H672L668 681H237ZM345 867H385L503 757H473L345 867Z" />
<glyph unicode="&#xc9;" glyph-name="Eacute" horiz-adv-x="668" d="M237 681L174 365H560L556 346H170L105 19H551L547 0H81L221 700H672L668 681H237ZM564 867H606L444 757H412L564 867Z" />
<glyph unicode="&#xca;" glyph-name="Ecircumflex" horiz-adv-x="668" d="M237 681L174 365H560L556 346H170L105 19H551L547 0H81L221 700H672L668 681H237ZM571 757L469 850L349 757H320L454 867H486L596 757H571Z" />
<glyph unicode="&#xcb;" glyph-name="Edieresis" horiz-adv-x="668" d="M237 681L174 365H560L556 346H170L105 19H551L547 0H81L221 700H672L668 681H237ZM377 791T370 798T362 815Q362 826 370 834T389 843Q399 843 406 836T414 819Q414 808 406 800T387 791Q377
791 370 798ZM541 791T534 798T526 815Q526 826 534 834T553 843Q563 843 570 836T578 819Q578 808 570 800T551 791Q541 791 534 798Z" />
<glyph unicode="&#xcc;" glyph-name="Igrave" horiz-adv-x="286" d="M221 700H241L101 0H81L221 700ZM129 867H169L287 757H257L129 867Z" />
<glyph unicode="&#xcd;" glyph-name="Iacute" horiz-adv-x="286" d="M221 700H241L101 0H81L221 700ZM348 867H390L228 757H196L348 867Z" />
<glyph unicode="&#xce;" glyph-name="Icircumflex" horiz-adv-x="286" d="M221 700H241L101 0H81L221 700ZM355 757L253 850L133 757H104L238 867H270L380 757H355Z" />
<glyph unicode="&#xcf;" glyph-name="Idieresis" horiz-adv-x="286" d="M221 700H241L101 0H81L221 700ZM161 791T154 798T146 815Q146 826 154 834T173 843Q183 843 190 836T198 819Q198 808 190 800T171 791Q161 791 154 798ZM325 791T318 798T310 815Q310 826
318 834T337 843Q347 843 354 836T362 819Q362 808 354 800T335 791Q325 791 318 798Z" />
<glyph unicode="&#xd0;" glyph-name="Eth" horiz-adv-x="826" d="M221 700H472Q575 700 647 665T756 567T793 420Q793 299 740 204T587 54T357 0H81L221 700ZM359 19Q483 19 577 70T722 212T773 420Q773 541 696 611T470 681H237L105 19H359ZM41 365H401L397 346H37L41
365Z" />
<glyph unicode="&#xd1;" glyph-name="Ntilde" horiz-adv-x="816" d="M771 700L631 0H614L234 667L101 0H81L221 700H238L618 33L751 700H771ZM560 769T545 778T511 806Q495 822 483 830T455 838Q432 838 416 820T395 771H376Q381 810 403 833T456 857Q477 857
492 848T525 820Q542 804 554 796T581 788Q604 788 620 806T642 853H661Q655 815 634 792T581 769Q560 769 545 778Z" />
<glyph unicode="&#xd2;" glyph-name="Ograve" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782 541
706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70ZM404 867H444L562 757H532L404 867Z" />
<glyph unicode="&#xd3;" glyph-name="Oacute" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782 541
706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70ZM623 867H665L503 757H471L623 867Z" />
<glyph unicode="&#xd4;" glyph-name="Ocircumflex" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782
541 706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70ZM630 757L528 850L408 757H379L513 867H545L655 757H630Z" />
<glyph unicode="&#xd5;" glyph-name="Otilde" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782 541
706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70ZM570 769T555 778T521 806Q505 822 493 830T465 838Q442 838 426 820T405 771H386Q391 810 413 833T466 857Q487 857 502 848T535 820Q552 804 564 796T591 788Q614 788 630
806T652 853H671Q665 815 644 792T591 769Q570 769 555 778Z" />
<glyph unicode="&#xd6;" glyph-name="Odieresis" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782 541
706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70ZM436 791T429 798T421 815Q421 826 429 834T448 843Q458 843 465 836T473 819Q473 808 465 800T446 791Q436 791 429 798ZM600 791T593 798T585 815Q585 826 593 834T612 843Q622
843 629 836T637 819Q637 808 629 800T610 791Q600 791 593 798Z" />
<glyph unicode="&#xd7;" glyph-name="multiply" horiz-adv-x="560" d="M311 349L431 211L417 198L297 337L146 198L134 212L285 351L165 489L179 502L299 363L450 502L462 488L311 349Z" />
<glyph unicode="&#xd8;" glyph-name="Oslash" horiz-adv-x="836" d="M286 -3T215 32T108 131T71 280Q71 393 122 490T267 645T487 703Q587 703 658 668T765 569T802 420Q802 307 751 210T606 55T386 -3Q286 -3 215 32ZM504 16T594 70T733 217T782 420Q782 541
706 612T485 684Q369 684 279 630T140 483T91 280Q91 159 167 88T388 16Q504 16 594 70ZM813 770H838L57 -70H32L813 770Z" />
<glyph unicode="&#xd9;" glyph-name="Ugrave" horiz-adv-x="794" d="M248 -3T187 53T126 213Q126 254 134 293L215 700H235L154 295Q145 252 145 214Q145 118 200 67T360 16Q480 16 553 84T654 294L735 700H755L674 293Q615 -3 360 -3Q248 -3 187 53ZM383 867H423L541
757H511L383 867Z" />
<glyph unicode="&#xda;" glyph-name="Uacute" horiz-adv-x="794" d="M248 -3T187 53T126 213Q126 254 134 293L215 700H235L154 295Q145 252 145 214Q145 118 200 67T360 16Q480 16 553 84T654 294L735 700H755L674 293Q615 -3 360 -3Q248 -3 187 53ZM602 867H644L482
757H450L602 867Z" />
<glyph unicode="&#xdb;" glyph-name="Ucircumflex" horiz-adv-x="794" d="M248 -3T187 53T126 213Q126 254 134 293L215 700H235L154 295Q145 252 145 214Q145 118 200 67T360 16Q480 16 553 84T654 294L735 700H755L674 293Q615 -3 360 -3Q248 -3 187 53ZM609
757L507 850L387 757H358L492 867H524L634 757H609Z" />
<glyph unicode="&#xdc;" glyph-name="Udieresis" horiz-adv-x="794" d="M248 -3T187 53T126 213Q126 254 134 293L215 700H235L154 295Q145 252 145 214Q145 118 200 67T360 16Q480 16 553 84T654 294L735 700H755L674 293Q615 -3 360 -3Q248 -3 187 53ZM415 791T408
798T400 815Q400 826 408 834T427 843Q437 843 444 836T452 819Q452 808 444 800T425 791Q415 791 408 798ZM579 791T572 798T564 815Q564 826 572 834T591 843Q601 843 608 836T616 819Q616 808 608 800T589 791Q579 791 572 798Z" />
<glyph unicode="&#xdd;" glyph-name="Yacute" horiz-adv-x="610" d="M310 235L263 0H243L291 238L98 700H120L304 258L663 700H688L310 235ZM510 867H552L390 757H358L510 867Z" />
<glyph unicode="&#xde;" glyph-name="Thorn" horiz-adv-x="710" d="M547 599T608 551T670 413Q670 280 586 210T353 139H129L101 0H81L221 700H241L221 599H436Q547 599 608 551ZM495 158T572 223T650 413Q650 493 595 536T437 580H217L133 158H352Q495 158 572 223Z" />
<glyph unicode="&#xdf;" glyph-name="germandbls" horiz-adv-x="651" d="M502 378T545 339T588 233Q588 162 554 109T460 26T322 -3Q296 -3 265 1T215 14L223 33Q267 16 322 16Q396 16 451 42T537 118T568 233Q568 301 520 336T391 371H332L336 390Q408 390 464
415T551 487T583 597Q583 658 543 692T428 726Q227 726 183 506L82 0H62L163 507Q188 629 257 687T429 745Q510 745 556 706T603 597Q603 520 554 462T427 386Q502 378 545 339Z" />
<glyph unicode="&#xe0;" glyph-name="agrave" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400 488
450T338 501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM273 717H313L431 607H401L273 717Z" />
<glyph unicode="&#xe1;" glyph-name="aacute" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400 488
450T338 501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM492 717H534L372 607H340L492 717Z" />
<glyph unicode="&#xe2;" glyph-name="acircumflex" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400
488 450T338 501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM499 607L397 700L277 607H248L382 717H414L524 607H499Z" />
<glyph unicode="&#xe3;" glyph-name="atilde" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400 488
450T338 501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM439 619T424 628T390 656Q374 672 362 680T334 688Q311 688 295 670T274 621H255Q260 660 282 683T335 707Q356 707 371 698T404 670Q421 654 433 646T460 638Q483 638 499 656T521
703H540Q534 665 513 642T460 619Q439 619 424 628Z" />
<glyph unicode="&#xe4;" glyph-name="adieresis" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400
488 450T338 501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM305 641T298 648T290 665Q290 676 298 684T317 693Q327 693 334 686T342 669Q342 658 334 650T315 641Q305 641 298 648ZM469 641T462 648T454 665Q454 676 462 684T481 693Q491
693 498 686T506 669Q506 658 498 650T479 641Q469 641 462 648Z" />
<glyph unicode="&#xe5;" glyph-name="aring" horiz-adv-x="671" d="M608 517L505 0H485L512 135Q475 70 412 34T269 -3Q168 -3 109 53T49 207Q49 296 86 367T190 479T341 520Q433 520 488 476T554 349L588 517H608ZM348 16T409 54T506 159T541 309Q541 400 488
450T338 501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM363 597T337 623T311 687Q311 725 337 752T403 780Q442 780 469 753T496 687Q496 650 470 624T403 597Q363 597 337 623ZM435 616T455 636T476 687Q476 717 455 739T403 761Q372
761 352 740T331 687Q331 657 351 637T403 616Q435 616 455 636Z" />
<glyph unicode="&#xe6;" glyph-name="ae" horiz-adv-x="983" d="M466 261Q462 240 462 210Q462 116 516 66T673 16Q730 16 778 36T859 93L872 80Q838 42 786 20T671 -3Q575 -3 516 42T445 172Q417 85 352 41T206 -3Q128 -3 84 30T40 122Q40 196 96 238T252 280H449L459
331Q465 360 465 383Q465 501 322 501Q268 501 217 482T128 430L116 444Q155 479 210 499T323 520Q406 520 446 482T484 376Q521 444 583 482T720 520Q819 520 875 464T932 310Q932 287 926 261H466ZM658 501T606 473T518 395T469 280H911Q913 304 913 316Q913
404 860 452T719 501Q658 501 606 473ZM291 16T353 65T433 202L445 261H252Q161 261 111 225T60 123Q60 71 98 44T208 16Q291 16 353 65Z" />
<glyph unicode="&#xe7;" glyph-name="ccedilla" horiz-adv-x="545" d="M169 -3T109 53T49 207Q49 296 86 367T191 479T342 520Q407 520 454 498T527 433L512 421Q460 501 341 501Q263 501 201 463T104 358T69 208Q69 116 123 66T277 16Q332 16 380 36T460 94L472
80Q440 41 388 19T274 -3Q169 -3 109 53ZM185 -216T157 -189L171 -174Q196 -197 236 -197Q271 -197 292 -178T313 -127Q313 -104 297 -91T251 -77H237L275 2H294L265 -59Q297 -62 315 -80T334 -127Q334 -165 306 -190T235 -216Q185 -216 157 -189Z" />
<glyph unicode="&#xe8;" glyph-name="egrave" horiz-adv-x="589" d="M72 259Q69 235 69 210Q69 116 123 66T279 16Q337 16 386 36T467 93L479 80Q447 42 394 20T278 -3Q170 -3 110 52T50 210Q50 297 86 368T185 479T326 520Q424 520 480 464T537 310Q537 284 532
259H72ZM232 501T164 440T75 278H516Q518 291 518 316Q518 404 466 452T326 501Q232 501 164 440ZM244 717H284L402 607H372L244 717Z" />
<glyph unicode="&#xe9;" glyph-name="eacute" horiz-adv-x="589" d="M72 259Q69 235 69 210Q69 116 123 66T279 16Q337 16 386 36T467 93L479 80Q447 42 394 20T278 -3Q170 -3 110 52T50 210Q50 297 86 368T185 479T326 520Q424 520 480 464T537 310Q537 284 532
259H72ZM232 501T164 440T75 278H516Q518 291 518 316Q518 404 466 452T326 501Q232 501 164 440ZM463 717H505L343 607H311L463 717Z" />
<glyph unicode="&#xea;" glyph-name="ecircumflex" horiz-adv-x="589" d="M72 259Q69 235 69 210Q69 116 123 66T279 16Q337 16 386 36T467 93L479 80Q447 42 394 20T278 -3Q170 -3 110 52T50 210Q50 297 86 368T185 479T326 520Q424 520 480 464T537 310Q537
284 532 259H72ZM232 501T164 440T75 278H516Q518 291 518 316Q518 404 466 452T326 501Q232 501 164 440ZM470 607L368 700L248 607H219L353 717H385L495 607H470Z" />
<glyph unicode="&#xeb;" glyph-name="edieresis" horiz-adv-x="589" d="M72 259Q69 235 69 210Q69 116 123 66T279 16Q337 16 386 36T467 93L479 80Q447 42 394 20T278 -3Q170 -3 110 52T50 210Q50 297 86 368T185 479T326 520Q424 520 480 464T537 310Q537 284
532 259H72ZM232 501T164 440T75 278H516Q518 291 518 316Q518 404 466 452T326 501Q232 501 164 440ZM276 641T269 648T261 665Q261 676 269 684T288 693Q298 693 305 686T313 669Q313 658 305 650T286 641Q276 641 269 648ZM440 641T433 648T425 665Q425 676
433 684T452 693Q462 693 469 686T477 669Q477 658 469 650T450 641Q440 641 433 648Z" />
<glyph unicode="&#xec;" glyph-name="igrave" horiz-adv-x="250" d="M166 517H186L83 0H63L166 517ZM81 717H121L239 607H209L81 717Z" />
<glyph unicode="&#xed;" glyph-name="iacute" horiz-adv-x="250" d="M166 517H186L83 0H63L166 517ZM300 717H342L180 607H148L300 717Z" />
<glyph unicode="&#xee;" glyph-name="icircumflex" horiz-adv-x="250" d="M166 517H186L83 0H63L166 517ZM281 607L205 701L109 607H81L191 717H221L307 607H281Z" />
<glyph unicode="&#xef;" glyph-name="idieresis" horiz-adv-x="250" d="M166 517H186L83 0H63L166 517ZM138 641T132 648T125 665Q125 676 133 684T152 693Q162 693 168 686T175 669Q175 658 167 650T148 641Q138 641 132 648ZM250 641T244 648T237 665Q237 676
245 684T264 693Q274 693 280 686T287 669Q287 658 279 650T260 641Q250 641 244 648Z" />
<glyph unicode="&#xf0;" glyph-name="eth" horiz-adv-x="618" d="M592 582T592 450Q592 345 553 240T435 66T248 -3Q153 -3 98 46T42 180Q42 255 78 311T176 399T318 430Q411 430 467 380T524 247Q524 238 522 220Q548 270 560 330T572 448Q572 582 492 640L201
521L194 539L472 653Q416 684 333 684Q295 684 257 678T190 661L186 679Q212 690 252 696T332 703Q429 703 493 662L591 702L599 684L512 648Q592 582 592 450ZM314 16T373 47T469 131T506 246Q506 322 456 366T318 411Q243 411 185 382T95 301T62 181Q62 103 111
60T251 16Q314 16 373 47Z" />
<glyph unicode="&#xf1;" glyph-name="ntilde" horiz-adv-x="668" d="M482 520T528 477T574 360Q574 334 568 305L507 0H487L548 305Q554 334 554 358Q554 426 513 463T391 501Q292 501 227 446T140 287L83 0H63L166 517H186L161 391Q234 520 393 520Q482 520 528
477ZM457 619T442 628T408 656Q392 672 380 680T352 688Q329 688 313 670T292 621H273Q278 660 300 683T353 707Q374 707 389 698T422 670Q439 654 451 646T478 638Q501 638 517 656T539 703H558Q552 665 531 642T478 619Q457 619 442 628Z" />
<glyph unicode="&#xf2;" glyph-name="ograve" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338 501Q262
501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM261 717H301L419 607H389L261 717Z" />
<glyph unicode="&#xf3;" glyph-name="oacute" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338 501Q262
501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM480 717H522L360 607H328L480 717Z" />
<glyph unicode="&#xf4;" glyph-name="ocircumflex" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338
501Q262 501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM487 607L385 700L265 607H236L370 717H402L512 607H487Z" />
<glyph unicode="&#xf5;" glyph-name="otilde" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338 501Q262
501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM427 619T412 628T378 656Q362 672 350 680T322 688Q299 688 283 670T262 621H243Q248 660 270 683T323 707Q344 707 359 698T392 670Q409 654 421 646T448 638Q471 638 487 656T509 703H528Q522
665 501 642T448 619Q427 619 412 628Z" />
<glyph unicode="&#xf6;" glyph-name="odieresis" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338 501Q262
501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM293 641T286 648T278 665Q278 676 286 684T305 693Q315 693 322 686T330 669Q330 658 322 650T303 641Q293 641 286 648ZM457 641T450 648T442 665Q442 676 450 684T469 693Q479 693 486 686T494
669Q494 658 486 650T467 641Q457 641 450 648Z" />
<glyph unicode="&#xf7;" glyph-name="divide" horiz-adv-x="560" d="M324 504T316 512T308 530Q308 541 316 548T334 556Q345 556 352 549T360 530Q360 520 353 512T334 504Q324 504 316 512ZM95 359H506L502 340H91L95 359ZM252 144T244 152T236 170Q236 181
244 188T262 196Q273 196 280 189T288 170Q288 160 281 152T262 144Q252 144 244 152Z" />
<glyph unicode="&#xf8;" glyph-name="oslash" horiz-adv-x="610" d="M168 -3T109 53T49 207Q49 296 86 367T190 479T341 520Q442 520 501 464T561 310Q561 221 524 150T420 38T269 -3Q168 -3 109 53ZM348 16T409 54T506 159T541 309Q541 400 488 450T338 501Q262
501 201 463T104 358T69 208Q69 117 122 67T272 16Q348 16 409 54ZM579 588H604L29 -69H4L579 588Z" />
<glyph unicode="&#xf9;" glyph-name="ugrave" horiz-adv-x="664" d="M601 517L498 0H478L503 126Q430 -3 273 -3Q185 -3 140 40T94 157Q94 184 100 212L161 517H181L120 212Q114 184 114 158Q114 90 155 53T275 16Q373 16 438 71T524 230L581 517H601ZM286 717H326L444
607H414L286 717Z" />
<glyph unicode="&#xfa;" glyph-name="uacute" horiz-adv-x="664" d="M601 517L498 0H478L503 126Q430 -3 273 -3Q185 -3 140 40T94 157Q94 184 100 212L161 517H181L120 212Q114 184 114 158Q114 90 155 53T275 16Q373 16 438 71T524 230L581 517H601ZM505 717H547L385
607H353L505 717Z" />
<glyph unicode="&#xfb;" glyph-name="ucircumflex" horiz-adv-x="664" d="M601 517L498 0H478L503 126Q430 -3 273 -3Q185 -3 140 40T94 157Q94 184 100 212L161 517H181L120 212Q114 184 114 158Q114 90 155 53T275 16Q373 16 438 71T524 230L581 517H601ZM512
607L410 700L290 607H261L395 717H427L537 607H512Z" />
<glyph unicode="&#xfc;" glyph-name="udieresis" horiz-adv-x="664" d="M601 517L498 0H478L503 126Q430 -3 273 -3Q185 -3 140 40T94 157Q94 184 100 212L161 517H181L120 212Q114 184 114 158Q114 90 155 53T275 16Q373 16 438 71T524 230L581 517H601ZM318
641T311 648T303 665Q303 676 311 684T330 693Q340 693 347 686T355 669Q355 658 347 650T328 641Q318 641 311 648ZM482 641T475 648T467 665Q467 676 475 684T494 693Q504 693 511 686T519 669Q519 658 511 650T492 641Q482 641 475 648Z" />
<glyph unicode="&#xfd;" glyph-name="yacute" horiz-adv-x="508" d="M554 517L155 -90Q115 -150 80 -173T-3 -197Q-37 -197 -66 -185T-112 -151L-96 -136Q-63 -178 0 -178Q38 -178 70 -157T137 -81L192 3L58 517H79L207 23L530 517H554ZM414 717H456L294 607H262L414
717Z" />
<glyph unicode="&#xfe;" glyph-name="thorn" horiz-adv-x="671" d="M503 520T562 464T622 310Q622 221 585 150T481 38T330 -3Q238 -3 183 41T117 168L44 -194H24L211 742H231L159 382Q196 447 259 483T402 520Q503 520 562 464ZM409 16T470 54T567 159T602 309Q602
400 549 450T399 501Q323 501 262 463T165 358T130 208Q130 117 183 67T333 16Q409 16 470 54Z" />
<glyph unicode="&#xff;" glyph-name="ydieresis" horiz-adv-x="508" d="M554 517L155 -90Q115 -150 80 -173T-3 -197Q-37 -197 -66 -185T-112 -151L-96 -136Q-63 -178 0 -178Q38 -178 70 -157T137 -81L192 3L58 517H79L207 23L530 517H554ZM227 641T220 648T212
665Q212 676 220 684T239 693Q249 693 256 686T264 669Q264 658 256 650T237 641Q227 641 220 648ZM391 641T384 648T376 665Q376 676 384 684T403 693Q413 693 420 686T428 669Q428 658 420 650T401 641Q391 641 384 648Z" />
<glyph unicode="&#x2013;" glyph-name="endash" horiz-adv-x="500" d="M3 274H503L499 255H-1L3 274Z" />
<glyph unicode="&#x2014;" glyph-name="emdash" horiz-adv-x="1000" d="M3 274H1003L999 255H-1L3 274Z" />
<glyph unicode="&#x2018;" glyph-name="quoteleft" horiz-adv-x="182" d="M169 603T175 596T181 579Q181 569 174 561T155 553Q145 553 137 561T129 579Q129 589 133 597T138 608L199 742H217L160 604Q169 603 175 596Z" />
<glyph unicode="&#x2019;" glyph-name="quoteright" horiz-adv-x="182" d="M194 745T201 738T209 719Q209 709 205 701T200 690L139 556H121L178 694Q169 695 163 702T157 719Q157 730 165 737T183 745Q194 745 201 738Z" />
<glyph unicode="&#x201a;" glyph-name="quotesinglbase" horiz-adv-x="182" d="M55 49T62 42T70 23Q70 13 66 5T61 -6L0 -140H-18L39 -2Q30 -1 24 6T18 23Q18 34 26 41T44 49Q55 49 62 42Z" />
<glyph unicode="&#x201c;" glyph-name="quotedblleft" horiz-adv-x="312" d="M169 603T175 596T181 579Q181 569 174 561T155 553Q145 553 137 561T129 579Q129 589 133 597T138 608L199 742H217L160 604Q169 603 175 596ZM299 603T305 596T311 579Q311 569 304
561T285 553Q275 553 267 561T259 579Q259 589 263 597T268 608L329 742H347L290 604Q299 603 305 596Z" />
<glyph unicode="&#x201d;" glyph-name="quotedblright" horiz-adv-x="312" d="M194 745T201 738T209 719Q209 709 205 701T200 690L139 556H121L178 694Q169 695 163 702T157 719Q157 730 165 737T183 745Q194 745 201 738ZM324 745T331 738T339 719Q339 709 335
701T330 690L269 556H251L308 694Q299 695 293 702T287 719Q287 730 295 737T313 745Q324 745 331 738Z" />
<glyph unicode="&#x201e;" glyph-name="quotedblbase" horiz-adv-x="312" d="M55 49T62 42T70 23Q70 13 66 5T61 -6L0 -140H-18L39 -2Q30 -1 24 6T18 23Q18 34 26 41T44 49Q55 49 62 42ZM185 49T192 42T200 23Q200 13 196 5T191 -6L130 -140H112L169 -2Q160 -1
154 6T148 23Q148 34 156 41T174 49Q185 49 192 42Z" />
<glyph unicode="&#x2022;" glyph-name="bullet" horiz-adv-x="258" d="M112 225T100 237T87 267Q87 286 100 299T133 313Q150 313 162 301T175 271Q175 252 162 239T129 225Q112 225 100 237Z" />
<glyph unicode="&#x2039;" glyph-name="guilsinglleft" horiz-adv-x="273" d="M81 258L190 74H168L58 259L242 444H266L81 258Z" />
<glyph unicode="&#x203a;" glyph-name="guilsinglright" horiz-adv-x="273" d="M215 259L31 74H7L192 260L83 444H105L215 259Z" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 54 KiB

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