@watermarkinsights/ripple 3.13.0 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/cjs/{chartFunctions-34fdd3ce.js → chartFunctions-0ea0888f.js} +420 -420
- package/dist/cjs/{functions-120449cf.js → functions-8d3ceccd.js} +1894 -450
- package/dist/cjs/{global-c1940f7b.js → global-39ada944.js} +62 -62
- package/dist/cjs/{http-service-494d81de.js → http-service-9e8c4dd5.js} +49 -49
- package/dist/cjs/{index-acad7ab3.js → index-df6a3611.js} +4 -1
- package/dist/cjs/{interfaces-a3338581.js → interfaces-30a74c1f.js} +29 -29
- package/dist/cjs/loader.cjs.js +4 -4
- package/dist/cjs/priv-chart-popover.cjs.entry.js +87 -87
- package/dist/cjs/priv-datepicker.cjs.entry.js +658 -658
- package/dist/cjs/priv-navigator-button.cjs.entry.js +19 -19
- package/dist/cjs/priv-navigator-item.cjs.entry.js +24 -24
- package/dist/cjs/ripple.cjs.js +4 -4
- package/dist/cjs/wm-action-menu_2.cjs.entry.js +336 -336
- package/dist/cjs/wm-button.cjs.entry.js +242 -242
- package/dist/cjs/wm-chart-slice.cjs.entry.js +14 -14
- package/dist/cjs/wm-chart.cjs.entry.js +111 -111
- package/dist/cjs/wm-datepicker.cjs.entry.js +266 -266
- package/dist/cjs/wm-input.cjs.entry.js +135 -135
- package/dist/cjs/wm-modal-footer.cjs.entry.js +34 -34
- package/dist/cjs/wm-modal-header.cjs.entry.js +37 -37
- package/dist/cjs/wm-modal.cjs.entry.js +164 -164
- package/dist/cjs/wm-navigation_3.cjs.entry.js +228 -228
- package/dist/cjs/wm-navigator.cjs.entry.js +269 -269
- package/dist/cjs/wm-network-uploader.cjs.entry.js +455 -455
- package/dist/cjs/wm-option_2.cjs.entry.js +717 -710
- package/dist/cjs/wm-pagination.cjs.entry.js +168 -168
- package/dist/cjs/wm-progress-indicator_3.cjs.entry.js +130 -130
- package/dist/cjs/wm-search.cjs.entry.js +233 -233
- package/dist/cjs/wm-snackbar.cjs.entry.js +171 -171
- package/dist/cjs/wm-tab-item_3.cjs.entry.js +297 -297
- package/dist/cjs/wm-tag-input.cjs.entry.js +580 -580
- package/dist/cjs/wm-timepicker.cjs.entry.js +384 -384
- package/dist/cjs/wm-toggletip.cjs.entry.js +125 -125
- package/dist/cjs/wm-uploader.cjs.entry.js +630 -632
- package/dist/cjs/wm-wrapper.cjs.entry.js +13 -13
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/charts/priv-chart-popover/priv-chart-popover.js +258 -258
- package/dist/collection/components/charts/wm-chart/wm-chart-slice.js +115 -115
- package/dist/collection/components/charts/wm-chart/wm-chart.js +328 -328
- package/dist/collection/components/charts/wm-progress-monitor/wm-progress-indicator.js +195 -195
- package/dist/collection/components/charts/wm-progress-monitor/wm-progress-monitor.js +88 -88
- package/dist/collection/components/charts/wm-progress-monitor/wm-progress-slice.js +111 -111
- package/dist/collection/components/wm-action-menu/wm-action-menu.js +448 -448
- package/dist/collection/components/wm-button/wm-button.js +504 -504
- package/dist/collection/components/wm-datepicker/priv-datepicker/priv-datepicker.js +1024 -1024
- package/dist/collection/components/wm-datepicker/wm-datepicker.js +471 -471
- package/dist/collection/components/wm-input/wm-input.js +423 -423
- package/dist/collection/components/wm-menuitem/wm-menuitem.js +444 -444
- package/dist/collection/components/wm-modal/wm-modal-footer.js +136 -136
- package/dist/collection/components/wm-modal/wm-modal-header.js +87 -87
- package/dist/collection/components/wm-modal/wm-modal.js +461 -461
- package/dist/collection/components/wm-navigation/wm-navigation-hamburger.js +162 -162
- package/dist/collection/components/wm-navigation/wm-navigation-item.js +121 -121
- package/dist/collection/components/wm-navigation/wm-navigation.js +218 -218
- package/dist/collection/components/wm-navigator/priv-navigator-button/priv-navigator-button.js +97 -97
- package/dist/collection/components/wm-navigator/priv-navigator-item/priv-navigator-item.js +114 -114
- package/dist/collection/components/wm-navigator/wm-navigator.js +468 -468
- package/dist/collection/components/wm-option/wm-option.css +13 -0
- package/dist/collection/components/wm-option/wm-option.js +427 -419
- package/dist/collection/components/wm-pagination/wm-pagination.js +368 -368
- package/dist/collection/components/wm-search/wm-search.js +480 -480
- package/dist/collection/components/wm-select/wm-select.css +5 -2
- package/dist/collection/components/wm-select/wm-select.js +978 -978
- package/dist/collection/components/wm-snackbar/wm-snackbar.js +297 -297
- package/dist/collection/components/wm-tabs/wm-tab-item/wm-tab-item.js +216 -216
- package/dist/collection/components/wm-tabs/wm-tab-list/wm-tab-list.js +330 -330
- package/dist/collection/components/wm-tabs/wm-tab-panel/wm-tab-panel.js +104 -104
- package/dist/collection/components/wm-tag-input/wm-tag-input.js +810 -810
- package/dist/collection/components/wm-timepicker/wm-timepicker.js +583 -583
- package/dist/collection/components/wm-toggletip/wm-toggletip.js +241 -241
- package/dist/collection/components/wm-uploader/wm-network-uploader/wm-network-uploader.js +787 -787
- package/dist/collection/components/wm-uploader/wm-uploader.js +1072 -1077
- package/dist/collection/components/wm-wrapper/wm-wrapper.js +27 -27
- package/dist/collection/dev/scripts.js +20 -20
- package/dist/collection/global/__mocks__/functions.js +6 -6
- package/dist/collection/global/chartFunctions.js +421 -421
- package/dist/collection/global/functions.js +441 -441
- package/dist/collection/global/global.js +69 -69
- package/dist/collection/global/interfaces.js +49 -49
- package/dist/collection/global/services/__mocks__/http-service.js +130 -130
- package/dist/collection/global/services/http-service.js +50 -50
- package/dist/collection/lang/lang.js +5 -5
- package/dist/collection/lang/missing.js +43 -43
- package/dist/collection/lang/piglatin.js +93 -93
- package/dist/esm/{chartFunctions-20f05eb5.js → chartFunctions-6f90586d.js} +420 -420
- package/dist/esm/{functions-036af8dc.js → functions-11c0c4e2.js} +1894 -450
- package/dist/esm/{global-e98c740f.js → global-d36a84c5.js} +62 -62
- package/dist/esm/{http-service-3dc3b3e7.js → http-service-5d037e16.js} +49 -49
- package/dist/esm/{index-7603f98e.js → index-17c79cc6.js} +4 -1
- package/dist/esm/{interfaces-2b97fab2.js → interfaces-61c6305b.js} +29 -29
- package/dist/esm/loader.js +4 -4
- package/dist/esm/polyfills/core-js.js +0 -0
- package/dist/esm/polyfills/css-shim.js +1 -1
- package/dist/esm/polyfills/dom.js +0 -0
- package/dist/esm/polyfills/es5-html-element.js +0 -0
- package/dist/esm/polyfills/index.js +0 -0
- package/dist/esm/polyfills/system.js +0 -0
- package/dist/esm/priv-chart-popover.entry.js +87 -87
- package/dist/esm/priv-datepicker.entry.js +658 -658
- package/dist/esm/priv-navigator-button.entry.js +19 -19
- package/dist/esm/priv-navigator-item.entry.js +24 -24
- package/dist/esm/ripple.js +4 -4
- package/dist/esm/wm-action-menu_2.entry.js +336 -336
- package/dist/esm/wm-button.entry.js +242 -242
- package/dist/esm/wm-chart-slice.entry.js +14 -14
- package/dist/esm/wm-chart.entry.js +111 -111
- package/dist/esm/wm-datepicker.entry.js +266 -266
- package/dist/esm/wm-input.entry.js +135 -135
- package/dist/esm/wm-modal-footer.entry.js +34 -34
- package/dist/esm/wm-modal-header.entry.js +37 -37
- package/dist/esm/wm-modal.entry.js +164 -164
- package/dist/esm/wm-navigation_3.entry.js +228 -228
- package/dist/esm/wm-navigator.entry.js +269 -269
- package/dist/esm/wm-network-uploader.entry.js +455 -455
- package/dist/esm/wm-option_2.entry.js +717 -710
- package/dist/esm/wm-pagination.entry.js +168 -168
- package/dist/esm/wm-progress-indicator_3.entry.js +130 -130
- package/dist/esm/wm-search.entry.js +233 -233
- package/dist/esm/wm-snackbar.entry.js +171 -171
- package/dist/esm/wm-tab-item_3.entry.js +297 -297
- package/dist/esm/wm-tag-input.entry.js +580 -580
- package/dist/esm/wm-timepicker.entry.js +384 -384
- package/dist/esm/wm-toggletip.entry.js +125 -125
- package/dist/esm/wm-uploader.entry.js +630 -632
- package/dist/esm/wm-wrapper.entry.js +13 -13
- package/dist/esm-es5/{chartFunctions-20f05eb5.js → chartFunctions-6f90586d.js} +1 -1
- package/dist/esm-es5/functions-11c0c4e2.js +1 -0
- package/dist/esm-es5/{global-e98c740f.js → global-d36a84c5.js} +1 -1
- package/dist/esm-es5/{http-service-3dc3b3e7.js → http-service-5d037e16.js} +0 -0
- package/dist/esm-es5/{index-7603f98e.js → index-17c79cc6.js} +1 -1
- package/dist/esm-es5/{interfaces-2b97fab2.js → interfaces-61c6305b.js} +0 -0
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/priv-chart-popover.entry.js +1 -1
- package/dist/esm-es5/priv-datepicker.entry.js +1 -1
- package/dist/esm-es5/priv-navigator-button.entry.js +1 -1
- package/dist/esm-es5/priv-navigator-item.entry.js +1 -1
- package/dist/esm-es5/ripple.js +1 -1
- package/dist/esm-es5/wm-action-menu_2.entry.js +1 -1
- package/dist/esm-es5/wm-button.entry.js +1 -1
- package/dist/esm-es5/wm-chart-slice.entry.js +1 -1
- package/dist/esm-es5/wm-chart.entry.js +1 -1
- package/dist/esm-es5/wm-datepicker.entry.js +1 -1
- package/dist/esm-es5/wm-input.entry.js +1 -1
- package/dist/esm-es5/wm-modal-footer.entry.js +1 -1
- package/dist/esm-es5/wm-modal-header.entry.js +1 -1
- package/dist/esm-es5/wm-modal.entry.js +1 -1
- package/dist/esm-es5/wm-navigation_3.entry.js +1 -1
- package/dist/esm-es5/wm-navigator.entry.js +1 -1
- package/dist/esm-es5/wm-network-uploader.entry.js +1 -1
- package/dist/esm-es5/wm-option_2.entry.js +1 -1
- package/dist/esm-es5/wm-pagination.entry.js +1 -1
- package/dist/esm-es5/wm-progress-indicator_3.entry.js +1 -1
- package/dist/esm-es5/wm-search.entry.js +1 -1
- package/dist/esm-es5/wm-snackbar.entry.js +1 -1
- package/dist/esm-es5/wm-tab-item_3.entry.js +1 -1
- package/dist/esm-es5/wm-tag-input.entry.js +1 -1
- package/dist/esm-es5/wm-timepicker.entry.js +1 -1
- package/dist/esm-es5/wm-toggletip.entry.js +1 -1
- package/dist/esm-es5/wm-uploader.entry.js +1 -1
- package/dist/esm-es5/wm-wrapper.entry.js +1 -1
- package/dist/ripple/{p-1ccd994d.system.entry.js → p-06012eb7.system.entry.js} +1 -1
- package/dist/ripple/{p-06adbeb9.system.entry.js → p-07ebdcd4.system.entry.js} +1 -1
- package/dist/ripple/{p-f5df5903.system.js → p-08b7ec08.system.js} +0 -0
- package/dist/ripple/{p-7173b0a7.system.entry.js → p-08fc668c.system.entry.js} +1 -1
- package/dist/ripple/p-0e22a3a4.entry.js +1 -0
- package/dist/ripple/p-262c75ff.entry.js +1 -0
- package/dist/ripple/{p-2193190b.js → p-26f94f8f.js} +1 -1
- package/dist/ripple/{p-90ed3268.system.entry.js → p-27253ed2.system.entry.js} +1 -1
- package/dist/ripple/{p-0556279c.system.entry.js → p-2af0b657.system.entry.js} +1 -1
- package/dist/ripple/p-2e5cb321.entry.js +1 -0
- package/dist/ripple/{p-9d02957d.system.js → p-313b6073.system.js} +0 -0
- package/dist/ripple/{p-6bf5cbf4.system.entry.js → p-3e875e87.system.entry.js} +1 -1
- package/dist/ripple/p-4073ac6a.entry.js +1 -0
- package/dist/ripple/p-410687ea.entry.js +1 -0
- package/dist/ripple/p-41374812.system.js +1 -0
- package/dist/ripple/p-42dbd978.entry.js +1 -0
- package/dist/ripple/{p-752da0fb.system.entry.js → p-4439bdd1.system.entry.js} +1 -1
- package/dist/ripple/{p-bbcafbd6.system.entry.js → p-4650a83c.system.entry.js} +1 -1
- package/dist/ripple/{p-4ecd3430.js → p-490dafa4.js} +1 -1
- package/dist/ripple/p-4afa52d4.entry.js +1 -0
- package/dist/ripple/p-4f3f7b2b.entry.js +1 -0
- package/dist/ripple/p-5018f8ae.entry.js +1 -0
- package/dist/ripple/{p-cd3d74d1.system.entry.js → p-57a718f0.system.entry.js} +1 -1
- package/dist/ripple/p-57c94258.entry.js +1 -0
- package/dist/ripple/{p-1df2adee.system.entry.js → p-59678b70.system.entry.js} +1 -1
- package/dist/ripple/p-626d5017.entry.js +1 -0
- package/dist/ripple/{p-3a535823.system.js → p-6a8fd452.system.js} +1 -1
- package/dist/ripple/{p-c1443a0e.system.entry.js → p-6ffdab0d.system.entry.js} +1 -1
- package/dist/ripple/p-70d0e993.js +1 -0
- package/dist/ripple/{p-a0c3ef16.system.js → p-726b9452.system.js} +1 -1
- package/dist/ripple/p-758501d7.entry.js +1 -0
- package/dist/ripple/{p-af3ce4fc.system.entry.js → p-7cb0035a.system.entry.js} +1 -1
- package/dist/ripple/p-80a00759.entry.js +1 -0
- package/dist/ripple/p-80b62707.entry.js +1 -0
- package/dist/ripple/{p-995ba16f.system.entry.js → p-84d0d2ff.system.entry.js} +1 -1
- package/dist/ripple/p-86b9bfcf.system.entry.js +1 -0
- package/dist/ripple/{p-43f1298b.js → p-888bec42.js} +0 -0
- package/dist/ripple/p-8a2cabf2.entry.js +1 -0
- package/dist/ripple/{p-62eac2d6.system.entry.js → p-8b54c589.system.entry.js} +1 -1
- package/dist/ripple/{p-7ef6a7cf.system.entry.js → p-910b6dd5.system.entry.js} +1 -1
- package/dist/ripple/p-962f51ff.entry.js +1 -0
- package/dist/ripple/p-97683ddc.entry.js +1 -0
- package/dist/ripple/p-9c60325b.entry.js +1 -0
- package/dist/ripple/{p-fd8070fb.js → p-a6d6eae7.js} +0 -0
- package/dist/ripple/p-b0536ddb.entry.js +1 -0
- package/dist/ripple/{p-d48c56c7.system.entry.js → p-b4837126.system.entry.js} +1 -1
- package/dist/ripple/{p-04d8b674.system.js → p-b5b7c71f.system.js} +1 -1
- package/dist/ripple/{p-8612829b.system.entry.js → p-b793bc6f.system.entry.js} +1 -1
- package/dist/ripple/p-c2abdcba.js +1 -0
- package/dist/ripple/{p-04e44b30.system.entry.js → p-c49ef079.system.entry.js} +1 -1
- package/dist/ripple/{p-895f5ec5.system.entry.js → p-c4c21c82.system.entry.js} +1 -1
- package/dist/ripple/p-c656fcf1.entry.js +1 -0
- package/dist/ripple/p-caef11cc.entry.js +1 -0
- package/dist/ripple/p-cb357a84.entry.js +1 -0
- package/dist/ripple/p-d2a11410.entry.js +1 -0
- package/dist/ripple/{p-49fd7ede.system.entry.js → p-d927de70.system.entry.js} +1 -1
- package/dist/ripple/{p-ae6cfbca.system.entry.js → p-db44eb6f.system.entry.js} +1 -1
- package/dist/ripple/p-db899686.system.js +1 -0
- package/dist/ripple/{p-f23b3986.system.entry.js → p-dc7e5609.system.entry.js} +1 -1
- package/dist/ripple/p-dfa80ed1.entry.js +1 -0
- package/dist/ripple/p-e012273a.entry.js +1 -0
- package/dist/ripple/p-e4cb8aad.entry.js +1 -0
- package/dist/ripple/{p-e4439bc3.system.entry.js → p-f0d3ceb1.system.entry.js} +1 -1
- package/dist/ripple/{p-3b3e847c.system.entry.js → p-f17076c4.system.entry.js} +1 -1
- package/dist/ripple/p-fa632547.entry.js +1 -0
- package/dist/ripple/{p-0e9ccc6f.system.entry.js → p-fe4c1194.system.entry.js} +1 -1
- package/dist/ripple/{p-ca383a43.system.entry.js → p-ffc34819.system.entry.js} +1 -1
- package/dist/ripple/ripple.esm.js +1 -1
- package/dist/ripple/ripple.js +1 -1
- package/dist/types/components/charts/priv-chart-popover/priv-chart-popover.d.ts +27 -27
- package/dist/types/components/charts/wm-chart/wm-chart-slice.d.ts +11 -11
- package/dist/types/components/charts/wm-chart/wm-chart.d.ts +36 -36
- package/dist/types/components/charts/wm-progress-monitor/wm-progress-indicator.d.ts +27 -27
- package/dist/types/components/charts/wm-progress-monitor/wm-progress-monitor.d.ts +17 -17
- package/dist/types/components/charts/wm-progress-monitor/wm-progress-slice.d.ts +10 -10
- package/dist/types/components/wm-action-menu/wm-action-menu.d.ts +47 -47
- package/dist/types/components/wm-button/wm-button.d.ts +43 -43
- package/dist/types/components/wm-datepicker/priv-datepicker/priv-datepicker.d.ts +80 -80
- package/dist/types/components/wm-datepicker/wm-datepicker.d.ts +41 -41
- package/dist/types/components/wm-input/wm-input.d.ts +46 -46
- package/dist/types/components/wm-menuitem/wm-menuitem.d.ts +34 -34
- package/dist/types/components/wm-modal/wm-modal-footer.d.ts +14 -14
- package/dist/types/components/wm-modal/wm-modal-header.d.ts +11 -11
- package/dist/types/components/wm-modal/wm-modal.d.ts +41 -41
- package/dist/types/components/wm-navigation/wm-navigation-hamburger.d.ts +21 -21
- package/dist/types/components/wm-navigation/wm-navigation-item.d.ts +13 -13
- package/dist/types/components/wm-navigation/wm-navigation.d.ts +28 -28
- package/dist/types/components/wm-navigator/priv-navigator-button/priv-navigator-button.d.ts +10 -10
- package/dist/types/components/wm-navigator/priv-navigator-item/priv-navigator-item.d.ts +13 -13
- package/dist/types/components/wm-navigator/wm-navigator.d.ts +61 -61
- package/dist/types/components/wm-option/wm-option.d.ts +35 -35
- package/dist/types/components/wm-pagination/wm-pagination.d.ts +32 -32
- package/dist/types/components/wm-search/wm-search.d.ts +86 -86
- package/dist/types/components/wm-select/wm-select.d.ts +94 -93
- package/dist/types/components/wm-snackbar/wm-snackbar.d.ts +35 -35
- package/dist/types/components/wm-tabs/wm-tab-item/wm-tab-item.d.ts +38 -38
- package/dist/types/components/wm-tabs/wm-tab-list/wm-tab-list.d.ts +53 -53
- package/dist/types/components/wm-tabs/wm-tab-panel/wm-tab-panel.d.ts +20 -20
- package/dist/types/components/wm-tag-input/wm-tag-input.d.ts +92 -92
- package/dist/types/components/wm-timepicker/wm-timepicker.d.ts +61 -61
- package/dist/types/components/wm-toggletip/wm-toggletip.d.ts +27 -27
- package/dist/types/components/wm-uploader/wm-network-uploader/wm-network-uploader.d.ts +85 -85
- package/dist/types/components/wm-uploader/wm-uploader.d.ts +118 -119
- package/dist/types/components/wm-wrapper/wm-wrapper.d.ts +7 -7
- package/dist/types/components.d.ts +26 -26
- package/dist/types/global/__mocks__/functions.d.ts +6 -6
- package/dist/types/global/chartFunctions.d.ts +29 -29
- package/dist/types/global/functions.d.ts +42 -42
- package/dist/types/global/global.d.ts +1 -1
- package/dist/types/global/interfaces.d.ts +44 -44
- package/dist/types/global/services/__mocks__/http-service.d.ts +6 -6
- package/dist/types/global/services/http-service.d.ts +4 -4
- package/dist/types/lang/lang.d.ts +5 -5
- package/package.json +47 -47
- package/dist/esm-es5/functions-036af8dc.js +0 -15
- package/dist/ripple/p-17ceb8c1.entry.js +0 -1
- package/dist/ripple/p-1887286e.entry.js +0 -1
- package/dist/ripple/p-1d795f42.entry.js +0 -1
- package/dist/ripple/p-2996bfe6.entry.js +0 -1
- package/dist/ripple/p-2f860b24.entry.js +0 -1
- package/dist/ripple/p-358bde27.entry.js +0 -1
- package/dist/ripple/p-3680b55d.entry.js +0 -1
- package/dist/ripple/p-3a1d6fc4.entry.js +0 -1
- package/dist/ripple/p-4d59fe86.entry.js +0 -1
- package/dist/ripple/p-6aa6a818.entry.js +0 -1
- package/dist/ripple/p-726c979a.system.js +0 -15
- package/dist/ripple/p-7ae1a630.entry.js +0 -1
- package/dist/ripple/p-7ecbf258.entry.js +0 -1
- package/dist/ripple/p-7fae0cc2.entry.js +0 -1
- package/dist/ripple/p-8de546e8.entry.js +0 -1
- package/dist/ripple/p-93dee724.entry.js +0 -1
- package/dist/ripple/p-97c2b06f.entry.js +0 -1
- package/dist/ripple/p-9ae81a59.system.js +0 -1
- package/dist/ripple/p-9c92c93f.entry.js +0 -1
- package/dist/ripple/p-9e09d7a1.entry.js +0 -1
- package/dist/ripple/p-a04ba6c8.entry.js +0 -1
- package/dist/ripple/p-a9e0ce88.entry.js +0 -1
- package/dist/ripple/p-b3c71506.js +0 -1
- package/dist/ripple/p-bee0b62d.entry.js +0 -1
- package/dist/ripple/p-da403a48.system.entry.js +0 -1
- package/dist/ripple/p-de3367ee.js +0 -16
- package/dist/ripple/p-e083fca6.entry.js +0 -1
- package/dist/ripple/p-e524d462.entry.js +0 -1
- package/dist/ripple/p-e8d39f68.entry.js +0 -1
- package/dist/ripple/p-ed91be1a.entry.js +0 -1
- package/dist/ripple/p-fda61e7e.entry.js +0 -1
- package/dist/ripple/p-fe952112.entry.js +0 -1
|
@@ -1,421 +1,421 @@
|
|
|
1
|
-
import { h } from "@stencil/core";
|
|
2
|
-
import { checkForActiveElInShadow, debounce, findParentWithScrollbar, getPosition, intl } from "./functions";
|
|
3
|
-
// Components wm-chart and wm-progress-indicator share a significant
|
|
4
|
-
// portion of their code. It has been extracted here
|
|
5
|
-
const colors = {
|
|
6
|
-
salmon: "#ff5f4e",
|
|
7
|
-
cyan: "#19a1a9",
|
|
8
|
-
forest: "#088000",
|
|
9
|
-
sleet: "#7f97ad",
|
|
10
|
-
midnight: "#2e1b46",
|
|
11
|
-
lavender: "#8b86ca",
|
|
12
|
-
};
|
|
13
|
-
export const types = {
|
|
14
|
-
doughnut: {
|
|
15
|
-
size: 155,
|
|
16
|
-
colors: [colors.forest, "#bfbfbf"],
|
|
17
|
-
thickness: 0.73,
|
|
18
|
-
padding: 25,
|
|
19
|
-
isBar: false,
|
|
20
|
-
},
|
|
21
|
-
// deprecated hybrid chart type, should use Progress Indicator's "doughnut" instead
|
|
22
|
-
doughnut0: {
|
|
23
|
-
size: 155,
|
|
24
|
-
colors: [colors.forest, "#bfbfbf"],
|
|
25
|
-
thickness: 0.73,
|
|
26
|
-
padding: 25,
|
|
27
|
-
isBar: false,
|
|
28
|
-
},
|
|
29
|
-
doughnut1: {
|
|
30
|
-
size: 130,
|
|
31
|
-
colors: [colors.lavender, colors.midnight, "#d4d4d4"],
|
|
32
|
-
thickness: 0.5,
|
|
33
|
-
padding: 90,
|
|
34
|
-
isBar: false,
|
|
35
|
-
},
|
|
36
|
-
doughnut2: {
|
|
37
|
-
size: 130,
|
|
38
|
-
colors: [colors.cyan, colors.salmon, "#d4d4d4"],
|
|
39
|
-
thickness: 0.5,
|
|
40
|
-
padding: 90,
|
|
41
|
-
isBar: false,
|
|
42
|
-
},
|
|
43
|
-
doughnut3: {
|
|
44
|
-
size: 130,
|
|
45
|
-
colors: [colors.lavender, colors.midnight, "#919834", "#c177cf", "#c16e00", "#029af2", "#2a6993"],
|
|
46
|
-
thickness: 0.5,
|
|
47
|
-
padding: 90,
|
|
48
|
-
isBar: false,
|
|
49
|
-
},
|
|
50
|
-
bar: {
|
|
51
|
-
size: 350,
|
|
52
|
-
colors: [colors.forest, "#bfbfbf"],
|
|
53
|
-
padding: 0,
|
|
54
|
-
isBar: true,
|
|
55
|
-
},
|
|
56
|
-
// deprecated hybrid chart type, should use Progress Indicator's "bar" instead
|
|
57
|
-
bar1: {
|
|
58
|
-
size: 350,
|
|
59
|
-
colors: [colors.forest, "#bfbfbf"],
|
|
60
|
-
padding: 0,
|
|
61
|
-
isBar: true,
|
|
62
|
-
},
|
|
63
|
-
bar2: {
|
|
64
|
-
size: 400,
|
|
65
|
-
colors: ["#d4d4d4", colors.sleet, colors.cyan, colors.salmon],
|
|
66
|
-
padding: 0,
|
|
67
|
-
isBar: true,
|
|
68
|
-
},
|
|
69
|
-
bar3: {
|
|
70
|
-
size: 300,
|
|
71
|
-
colors: ["#0d696e", colors.cyan, "#8e4129", colors.salmon],
|
|
72
|
-
padding: 0,
|
|
73
|
-
isBar: true,
|
|
74
|
-
},
|
|
75
|
-
bar4: {
|
|
76
|
-
size: 400,
|
|
77
|
-
colors: ["#d4d4d4", colors.sleet, "#33a919"],
|
|
78
|
-
padding: 0,
|
|
79
|
-
isBar: true,
|
|
80
|
-
},
|
|
81
|
-
bar5: {
|
|
82
|
-
size: 400,
|
|
83
|
-
colors: [
|
|
84
|
-
"#d4d4d4",
|
|
85
|
-
colors.lavender,
|
|
86
|
-
colors.midnight,
|
|
87
|
-
"#919834",
|
|
88
|
-
"#c177cf",
|
|
89
|
-
"#c16e00",
|
|
90
|
-
"#029af2",
|
|
91
|
-
"#2a6993",
|
|
92
|
-
],
|
|
93
|
-
padding: 0,
|
|
94
|
-
isBar: true,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
export function amountToPercent(val, total, asInt) {
|
|
98
|
-
return asInt ? Math.round((val * 100) / total) : Math.round((val * 10000) / total) / 100; // with 2 decimals
|
|
99
|
-
}
|
|
100
|
-
export function amountToDegree(val, total) {
|
|
101
|
-
// In a circle of {total}, determine degrees of slice {val}
|
|
102
|
-
return (val * 360) / total;
|
|
103
|
-
}
|
|
104
|
-
export function toFixed(number) {
|
|
105
|
-
return parseFloat((Math.floor(number * 100) / 100).toFixed(2));
|
|
106
|
-
}
|
|
107
|
-
export function polarToCartesian(half, radius, startAngle, endAngle) {
|
|
108
|
-
var x = toFixed(half + half * radius * Math.cos((Math.PI * startAngle) / 180));
|
|
109
|
-
var y = toFixed(half + half * radius * Math.sin((Math.PI * startAngle) / 180));
|
|
110
|
-
if (endAngle !== undefined) {
|
|
111
|
-
// if a 2nd angle value was passed, return 2 pairs of coords
|
|
112
|
-
var x2 = toFixed(half + half * radius * Math.cos((Math.PI * endAngle) / 180));
|
|
113
|
-
var y2 = toFixed(half + half * radius * Math.sin((Math.PI * endAngle) / 180));
|
|
114
|
-
return { x1: x, y1: y, x2, y2 };
|
|
115
|
-
}
|
|
116
|
-
return { x, y };
|
|
117
|
-
}
|
|
118
|
-
function getArc(radius, largeArcFlag, x, y, chartSize) {
|
|
119
|
-
var z = toFixed((chartSize / 2) * radius);
|
|
120
|
-
return `A ${z}, ${z} 0 ${largeArcFlag} ${toFixed(x)}, ${toFixed(y)}`;
|
|
121
|
-
}
|
|
122
|
-
function handleSliceKeyDown(ev) {
|
|
123
|
-
if (this.popoverEl && this.popoverEl.open && ev.key === "Enter") {
|
|
124
|
-
const popoverBtn = this.popoverEl.querySelector("button");
|
|
125
|
-
popoverBtn && popoverBtn.click();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
export function handleSliceClick(ev, s) {
|
|
129
|
-
if (this.popoverEl && !this.isTabbing) {
|
|
130
|
-
s.coords = { x: ev.clientX, y: ev.clientY };
|
|
131
|
-
openPopover.call(this, s);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function handleSliceFocus(ev, s) {
|
|
135
|
-
if (this.popoverEl && this.isTabbing) {
|
|
136
|
-
s.coords = getPosition(ev.target);
|
|
137
|
-
openPopover.call(this, s);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
export function handleChartKeydown(ev) {
|
|
141
|
-
switch (ev.key) {
|
|
142
|
-
// arrow up / left
|
|
143
|
-
case "ArrowUp":
|
|
144
|
-
case "ArrowLeft":
|
|
145
|
-
ev.preventDefault();
|
|
146
|
-
this.isTabbing = true; // shd already be true. just in case user clicked on chart then pressed an arrow key
|
|
147
|
-
focusPrevious.call(this);
|
|
148
|
-
break;
|
|
149
|
-
// arrow right / down
|
|
150
|
-
case "ArrowRight":
|
|
151
|
-
case "ArrowDown":
|
|
152
|
-
ev.preventDefault();
|
|
153
|
-
this.isTabbing = true; // shd already be true. just in case user clicked on chart then pressed an arrow key
|
|
154
|
-
focusNext.call(this);
|
|
155
|
-
break;
|
|
156
|
-
// tab
|
|
157
|
-
case "Tab":
|
|
158
|
-
exitChart.call(this);
|
|
159
|
-
break;
|
|
160
|
-
case "Escape":
|
|
161
|
-
this.popoverEl.open = false;
|
|
162
|
-
this.userIsNavigating = false;
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
export function openPopover(s) {
|
|
167
|
-
if (!!this.popoverEl && !!s.title && !!s.text) {
|
|
168
|
-
this.popoverEl.popoverTitle = s.title;
|
|
169
|
-
this.popoverEl.popoverText = s.text;
|
|
170
|
-
this.popoverEl.buttonText = s.buttonText;
|
|
171
|
-
this.popoverEl.coords = s.coords;
|
|
172
|
-
this.popoverEl.sliceRef = s.sliceRef;
|
|
173
|
-
window.setTimeout(() => {
|
|
174
|
-
if (this.popoverEl) {
|
|
175
|
-
this.popoverEl.open = true;
|
|
176
|
-
}
|
|
177
|
-
}, 30);
|
|
178
|
-
const debouncedClosePopover = debounce(async () => {
|
|
179
|
-
this.popoverEl.open = false;
|
|
180
|
-
}, 10);
|
|
181
|
-
// set up event listeners for scrolling
|
|
182
|
-
// to close popover on page scroll
|
|
183
|
-
document.addEventListener("scroll", () => {
|
|
184
|
-
debouncedClosePopover();
|
|
185
|
-
});
|
|
186
|
-
// ... and on parent scroll
|
|
187
|
-
const scrollableParent = findParentWithScrollbar(this.el);
|
|
188
|
-
if (!!scrollableParent) {
|
|
189
|
-
scrollableParent.addEventListener("scroll", () => {
|
|
190
|
-
debouncedClosePopover();
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
function focusNext() {
|
|
196
|
-
const activeEl = checkForActiveElInShadow(document.activeElement);
|
|
197
|
-
const index =
|
|
198
|
-
// if the active el is not in the array the first element gets focused
|
|
199
|
-
(this.sliceEls.indexOf(activeEl) + 1) % this.sliceEls.length;
|
|
200
|
-
focusSlice.call(this, index);
|
|
201
|
-
}
|
|
202
|
-
function focusPrevious() {
|
|
203
|
-
if (this.sliceEls) {
|
|
204
|
-
const activeEl = checkForActiveElInShadow(document.activeElement);
|
|
205
|
-
let index = this.sliceEls.indexOf(activeEl);
|
|
206
|
-
if (index === -1) {
|
|
207
|
-
// not in the array : focus the first slice
|
|
208
|
-
index = 0;
|
|
209
|
-
}
|
|
210
|
-
else if (index === 0) {
|
|
211
|
-
// first slice : focus the last slice
|
|
212
|
-
index = this.sliceEls.length - 1;
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
// anything else: focus previous
|
|
216
|
-
index -= 1;
|
|
217
|
-
}
|
|
218
|
-
focusSlice.call(this, index);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function focusSlice(index) {
|
|
222
|
-
if (this.sliceEls && this.el) {
|
|
223
|
-
this.userIsNavigating = true;
|
|
224
|
-
if (this.popoverEl) {
|
|
225
|
-
this.popoverEl.open = false;
|
|
226
|
-
}
|
|
227
|
-
this.el.tabIndex = -1;
|
|
228
|
-
// @ts-ignore
|
|
229
|
-
this.el.focusable = false; // for Edge
|
|
230
|
-
this.sliceEls.map((p) => {
|
|
231
|
-
p.tabIndex = -1;
|
|
232
|
-
// @ts-ignore
|
|
233
|
-
p.focusable = false; // for Edge
|
|
234
|
-
});
|
|
235
|
-
this.sliceEls[index].tabIndex = 0;
|
|
236
|
-
// @ts-ignore
|
|
237
|
-
this.sliceEls[index].focusable = true; // for Edge
|
|
238
|
-
this.sliceEls[index].focus();
|
|
239
|
-
window.setTimeout(() => {
|
|
240
|
-
if (this.popoverEl) {
|
|
241
|
-
this.popoverEl.open = true;
|
|
242
|
-
}
|
|
243
|
-
}, 10);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
export function exitChart() {
|
|
247
|
-
this.sliceEls &&
|
|
248
|
-
this.sliceEls.map((p) => {
|
|
249
|
-
p.tabIndex = -1;
|
|
250
|
-
// @ts-ignore
|
|
251
|
-
p.focusable = false; // for Edge
|
|
252
|
-
});
|
|
253
|
-
this.userIsNavigating = false;
|
|
254
|
-
// delay so that we can tab out of component before chart becomes focusable again
|
|
255
|
-
// and in case user was still pressing an arrow key when they pressed tab
|
|
256
|
-
window.setTimeout(() => {
|
|
257
|
-
if (this.el) {
|
|
258
|
-
this.el.tabIndex = 0;
|
|
259
|
-
// @ts-ignore
|
|
260
|
-
this.el.focusable = true; // for Edge
|
|
261
|
-
if (this.popoverEl) {
|
|
262
|
-
this.popoverEl.open = false;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}, 100);
|
|
266
|
-
}
|
|
267
|
-
export async function getData(chartType) {
|
|
268
|
-
this.slicesData = [];
|
|
269
|
-
let acc = 0;
|
|
270
|
-
const children = Array.from(this.el.children);
|
|
271
|
-
this.total = children.reduce((total, slice) => (total += parseInt(slice.getAttribute("amount") || "0")), 0);
|
|
272
|
-
children.forEach((c, i) => {
|
|
273
|
-
const amount = parseInt(c.getAttribute("amount") || "0");
|
|
274
|
-
const perc = amountToPercent(amount, this.total, true);
|
|
275
|
-
// determine whether the slice is in a cluster of small values
|
|
276
|
-
// to avoid percentage text overlap for small values
|
|
277
|
-
const prev = children[i === 0 ? children.length - 1 : i - 1];
|
|
278
|
-
const prevPerc = amountToPercent(parseInt(prev.getAttribute("amount") || "0"), this.total, true);
|
|
279
|
-
const next = children[i === children.length - 1 ? 0 : i + 1];
|
|
280
|
-
const nextPerc = amountToPercent(parseInt(next.getAttribute("amount") || "0"), this.total, true);
|
|
281
|
-
const isSmall = perc < 4;
|
|
282
|
-
const prevIsSmall = prevPerc < 5;
|
|
283
|
-
const nextIsSmall = nextPerc < 5;
|
|
284
|
-
let inSmallCluster = isSmall && (prevIsSmall || nextIsSmall);
|
|
285
|
-
// because <1% slice percentage text has an additional character
|
|
286
|
-
// the inSmallCluster threshold needs to be widened for that slice only
|
|
287
|
-
const lessThanOnePerc = perc === 0 && amount > 0;
|
|
288
|
-
if (lessThanOnePerc && (nextPerc < 8 || prevPerc < 8)) {
|
|
289
|
-
inSmallCluster = true;
|
|
290
|
-
}
|
|
291
|
-
// for bar5, first color should be skipped unless notStartedColor is set to true
|
|
292
|
-
const ind = chartType === "bar5" ? (this.notStartedColor ? i : i + 1) : i;
|
|
293
|
-
const color = types[chartType].colors[ind];
|
|
294
|
-
const sliceData = {
|
|
295
|
-
amount: amount,
|
|
296
|
-
perc: perc,
|
|
297
|
-
legend: c.getAttribute("legend"),
|
|
298
|
-
color: color || "#d4d4d4",
|
|
299
|
-
offset: acc,
|
|
300
|
-
id: `${this.uid}-${i + 1}`,
|
|
301
|
-
title: c.getAttribute("popover-title"),
|
|
302
|
-
text: c.getAttribute("popover-text"),
|
|
303
|
-
buttonText: c.getAttribute("popover-button-text"),
|
|
304
|
-
sliceRef: c,
|
|
305
|
-
inSmallCluster: inSmallCluster,
|
|
306
|
-
};
|
|
307
|
-
acc += amount;
|
|
308
|
-
this.slicesData.push(sliceData);
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
function getPathData(amount, offset, chartType) {
|
|
312
|
-
const startAngle = amountToDegree(offset, this.total) - 90; // start at noon, not at 3 o'clock
|
|
313
|
-
const activeAngle = (amount / this.total) * 360;
|
|
314
|
-
let endAngle = startAngle + activeAngle;
|
|
315
|
-
const largeArcFlagOuter = activeAngle > 180 ? "1 1" : "0 1";
|
|
316
|
-
const largeArcFlagInner = activeAngle > 180 ? "1 0" : "0 0";
|
|
317
|
-
const half = this.chartData.size / 2;
|
|
318
|
-
const innerRadius = this.chartData.thickness;
|
|
319
|
-
const outerRadius = 1;
|
|
320
|
-
const isHybridDoughnut = chartType === "doughnut0" || chartType === "doughnut";
|
|
321
|
-
const outerSeparatorOffset = 1.5;
|
|
322
|
-
const innerSeparatorOffset = isHybridDoughnut ? 2.25 : 3;
|
|
323
|
-
if (activeAngle === 360) {
|
|
324
|
-
// fix to avoid bad svg shape when the path goes all around (100%)
|
|
325
|
-
endAngle -= 0.01;
|
|
326
|
-
}
|
|
327
|
-
const outerCoords = polarToCartesian(half, outerRadius, startAngle + outerSeparatorOffset, // Addition for slice separator
|
|
328
|
-
endAngle);
|
|
329
|
-
const innerCoords = polarToCartesian(half, innerRadius, startAngle + innerSeparatorOffset, // Addition for slice separator
|
|
330
|
-
endAngle);
|
|
331
|
-
const moveTo = `M ${outerCoords.x1}, ${outerCoords.y1} `;
|
|
332
|
-
const arc1 = getArc(outerRadius, largeArcFlagOuter, outerCoords.x2, outerCoords.y2, this.chartData.size);
|
|
333
|
-
const line = ` L ${innerCoords.x2}, ${innerCoords.y2} `;
|
|
334
|
-
const arc2 = getArc(innerRadius, largeArcFlagInner, innerCoords.x1, innerCoords.y1, this.chartData.size);
|
|
335
|
-
return moveTo + arc1 + line + arc2 + " z";
|
|
336
|
-
}
|
|
337
|
-
function renderFilter() {
|
|
338
|
-
return (h("defs", null,
|
|
339
|
-
h("filter", { id: "wmHoverDropShadow" },
|
|
340
|
-
h("feGaussianBlur", { stdDeviation: "3" }),
|
|
341
|
-
h("feOffset", { result: "offsetblur" }),
|
|
342
|
-
h("feFlood", { "flood-color": "#333" }),
|
|
343
|
-
h("feComposite", { operator: "in", in2: "offsetblur" }),
|
|
344
|
-
h("feMerge", null,
|
|
345
|
-
h("feMergeNode", null),
|
|
346
|
-
h("feMergeNode", { in: "SourceGraphic" })))));
|
|
347
|
-
}
|
|
348
|
-
export function renderDoughnut(chartType) {
|
|
349
|
-
const outerSize = this.chartData.size + this.chartData.padding;
|
|
350
|
-
const isHybridDoughnut = chartType === "doughnut0" || chartType === "doughnut";
|
|
351
|
-
return (h("div", { class: "chart-wrapper doughnut-wrapper" },
|
|
352
|
-
h("svg", { width: outerSize + "px", height: outerSize + "px", id: `graphic-${this.uid}`, class: "doughnut-svg" },
|
|
353
|
-
renderFilter(),
|
|
354
|
-
this.slicesData.map((s) => renderPath.call(this, s, chartType)),
|
|
355
|
-
isHybridDoughnut ? (h("text", { class: "value", x: "50%", y: "50%", "font-size": "1.5rem", "font-weight": "500", "text-anchor": "middle", "dominant-baseline": "middle" }, amountToPercent(this.slicesData[0].amount, this.total, true) + "%")) : (h("g", { transform: `translate(${this.chartData.padding / 2}, ${this.chartData.padding / 2})`, "text-anchor": "middle", "dominant-baseline": "middle" }, this.slicesData.map((s) => (s.amount > 0 ? renderDoughnutText.call(this, s) : "")))))));
|
|
356
|
-
}
|
|
357
|
-
function renderPath(s, chartType) {
|
|
358
|
-
return (h("g", { transform: `translate(${this.chartData.padding / 2}, ${this.chartData.padding / 2})` },
|
|
359
|
-
h("path", { id: s.id, class: "segment doughnut-segment", fill: s.amount ? s.color : "transparent", d: getPathData.call(this, s.amount, s.offset, chartType), onClick: (ev) => handleSliceClick.call(this, ev, s), onFocus: (ev) => handleSliceFocus.call(this, ev, s), onKeyDown: (ev) => handleSliceKeyDown.call(this, ev), role: "img", "aria-label": s.legend })));
|
|
360
|
-
}
|
|
361
|
-
function renderDoughnutText(s) {
|
|
362
|
-
if (!s.inSmallCluster) {
|
|
363
|
-
const arcMiddle = amountToDegree(s.offset + s.amount / 2, this.total);
|
|
364
|
-
let { x, y } = polarToCartesian(this.chartData.size / 2, 1.4, arcMiddle - 90);
|
|
365
|
-
return (h("text", { class: "value", x: x + "px", y: y + "px" }, `${s.perc > 0 ? s.perc : "<1"}%`));
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
export function renderBar(chartType) {
|
|
369
|
-
const isHybridBar = chartType === "bar1" || chartType === "bar";
|
|
370
|
-
return (h("div", { class: "chart-wrapper bar-wrapper" },
|
|
371
|
-
isHybridBar ? (h("div", { class: "single-perc" }, amountToPercent(this.slicesData[0].amount, this.total, true) + "%")) : (""),
|
|
372
|
-
this.chartType === "bar3" && this.drawAxis(),
|
|
373
|
-
h("div", { class: {
|
|
374
|
-
"inner-bar-wrapper": true,
|
|
375
|
-
"show-values": this.tempValueFormat === "percentage" || this.tempValueFormat === "amount",
|
|
376
|
-
} },
|
|
377
|
-
!isHybridBar ? (h("div", { class: "values" }, this.slicesData.map((s, idx) => (s.perc > 0 ? this.renderBarText(s, idx) : "")))) : (""),
|
|
378
|
-
h("div", { class: "bar-segments-wrapper" }, this.slicesData.map((s, idx) => renderBarSegment.call(this, s, idx))),
|
|
379
|
-
isHybridBar ? renderCompletionMessage.call(this) : "")));
|
|
380
|
-
}
|
|
381
|
-
function renderBarSegment(s, idx) {
|
|
382
|
-
const isLastSlice = idx !== this.slicesData.length - 1;
|
|
383
|
-
const width = `calc(${amountToPercent(s.amount, this.total, false)}%${isLastSlice ? " - 2px" : ""})`;
|
|
384
|
-
return (h("div", { class: `segment bar-segment ${amountToPercent(s.amount, this.total, false) === 0 ? "zero" : ""}`, style: {
|
|
385
|
-
backgroundColor: s.color,
|
|
386
|
-
width: width,
|
|
387
|
-
}, onClick: (ev) => handleSliceClick.call(this, ev, s), onFocus: (ev) => handleSliceFocus.call(this, ev, s), onKeyDown: (ev) => handleSliceKeyDown.call(this, ev) },
|
|
388
|
-
h("span", { class: "sr-only" }, s.legend)));
|
|
389
|
-
}
|
|
390
|
-
export function renderLegend() {
|
|
391
|
-
// legend is hidden for bar1 type regardless of showLegend value
|
|
392
|
-
if (this.showLegend) {
|
|
393
|
-
const hasCluster = this.slicesData.reduce((hasCluster, cur) => (hasCluster = cur.inSmallCluster ? true : hasCluster), false);
|
|
394
|
-
return (h("div", { class: "legend-wrapper" },
|
|
395
|
-
h("div", { class: `legend ${this.mode === "bar" ? "--top" : "--bottom"}`, "aria-hidden": "true" }, this.total > 0
|
|
396
|
-
? this.slicesData.map((s) => {
|
|
397
|
-
// when both legend and amount are omitted, the legend is not shown for that particular option (it's been deactivated by the user)
|
|
398
|
-
if (!!s.amount || !!s.legend) {
|
|
399
|
-
return (h("div", { class: "legend-item" },
|
|
400
|
-
h("div", { class: "legend-color", style: { "background-color": s.color } }),
|
|
401
|
-
h("div", { class: "legend-text" }, s.legend)));
|
|
402
|
-
}
|
|
403
|
-
})
|
|
404
|
-
: ""),
|
|
405
|
-
!this.chartData.isBar && hasCluster ? (h("div", { class: "cluster-warning" },
|
|
406
|
-
intl.formatMessage({
|
|
407
|
-
id: "chart.hiddenPercentages",
|
|
408
|
-
defaultMessage: "Percentages smaller than 5% are not shown when too close to each other.",
|
|
409
|
-
}),
|
|
410
|
-
h("br", null),
|
|
411
|
-
intl.formatMessage({
|
|
412
|
-
id: "chart.clickToSeeDetails",
|
|
413
|
-
defaultMessage: "Click or use arrow keys to see details.",
|
|
414
|
-
}))) : ("")));
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
export function renderCompletionMessage() {
|
|
418
|
-
if (this.completionMessage) {
|
|
419
|
-
return h("div", { class: "completion-message" }, this.completionMessage);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
1
|
+
import { h } from "@stencil/core";
|
|
2
|
+
import { checkForActiveElInShadow, debounce, findParentWithScrollbar, getPosition, intl } from "./functions";
|
|
3
|
+
// Components wm-chart and wm-progress-indicator share a significant
|
|
4
|
+
// portion of their code. It has been extracted here
|
|
5
|
+
const colors = {
|
|
6
|
+
salmon: "#ff5f4e",
|
|
7
|
+
cyan: "#19a1a9",
|
|
8
|
+
forest: "#088000",
|
|
9
|
+
sleet: "#7f97ad",
|
|
10
|
+
midnight: "#2e1b46",
|
|
11
|
+
lavender: "#8b86ca",
|
|
12
|
+
};
|
|
13
|
+
export const types = {
|
|
14
|
+
doughnut: {
|
|
15
|
+
size: 155,
|
|
16
|
+
colors: [colors.forest, "#bfbfbf"],
|
|
17
|
+
thickness: 0.73,
|
|
18
|
+
padding: 25,
|
|
19
|
+
isBar: false,
|
|
20
|
+
},
|
|
21
|
+
// deprecated hybrid chart type, should use Progress Indicator's "doughnut" instead
|
|
22
|
+
doughnut0: {
|
|
23
|
+
size: 155,
|
|
24
|
+
colors: [colors.forest, "#bfbfbf"],
|
|
25
|
+
thickness: 0.73,
|
|
26
|
+
padding: 25,
|
|
27
|
+
isBar: false,
|
|
28
|
+
},
|
|
29
|
+
doughnut1: {
|
|
30
|
+
size: 130,
|
|
31
|
+
colors: [colors.lavender, colors.midnight, "#d4d4d4"],
|
|
32
|
+
thickness: 0.5,
|
|
33
|
+
padding: 90,
|
|
34
|
+
isBar: false,
|
|
35
|
+
},
|
|
36
|
+
doughnut2: {
|
|
37
|
+
size: 130,
|
|
38
|
+
colors: [colors.cyan, colors.salmon, "#d4d4d4"],
|
|
39
|
+
thickness: 0.5,
|
|
40
|
+
padding: 90,
|
|
41
|
+
isBar: false,
|
|
42
|
+
},
|
|
43
|
+
doughnut3: {
|
|
44
|
+
size: 130,
|
|
45
|
+
colors: [colors.lavender, colors.midnight, "#919834", "#c177cf", "#c16e00", "#029af2", "#2a6993"],
|
|
46
|
+
thickness: 0.5,
|
|
47
|
+
padding: 90,
|
|
48
|
+
isBar: false,
|
|
49
|
+
},
|
|
50
|
+
bar: {
|
|
51
|
+
size: 350,
|
|
52
|
+
colors: [colors.forest, "#bfbfbf"],
|
|
53
|
+
padding: 0,
|
|
54
|
+
isBar: true,
|
|
55
|
+
},
|
|
56
|
+
// deprecated hybrid chart type, should use Progress Indicator's "bar" instead
|
|
57
|
+
bar1: {
|
|
58
|
+
size: 350,
|
|
59
|
+
colors: [colors.forest, "#bfbfbf"],
|
|
60
|
+
padding: 0,
|
|
61
|
+
isBar: true,
|
|
62
|
+
},
|
|
63
|
+
bar2: {
|
|
64
|
+
size: 400,
|
|
65
|
+
colors: ["#d4d4d4", colors.sleet, colors.cyan, colors.salmon],
|
|
66
|
+
padding: 0,
|
|
67
|
+
isBar: true,
|
|
68
|
+
},
|
|
69
|
+
bar3: {
|
|
70
|
+
size: 300,
|
|
71
|
+
colors: ["#0d696e", colors.cyan, "#8e4129", colors.salmon],
|
|
72
|
+
padding: 0,
|
|
73
|
+
isBar: true,
|
|
74
|
+
},
|
|
75
|
+
bar4: {
|
|
76
|
+
size: 400,
|
|
77
|
+
colors: ["#d4d4d4", colors.sleet, "#33a919"],
|
|
78
|
+
padding: 0,
|
|
79
|
+
isBar: true,
|
|
80
|
+
},
|
|
81
|
+
bar5: {
|
|
82
|
+
size: 400,
|
|
83
|
+
colors: [
|
|
84
|
+
"#d4d4d4",
|
|
85
|
+
colors.lavender,
|
|
86
|
+
colors.midnight,
|
|
87
|
+
"#919834",
|
|
88
|
+
"#c177cf",
|
|
89
|
+
"#c16e00",
|
|
90
|
+
"#029af2",
|
|
91
|
+
"#2a6993",
|
|
92
|
+
],
|
|
93
|
+
padding: 0,
|
|
94
|
+
isBar: true,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
export function amountToPercent(val, total, asInt) {
|
|
98
|
+
return asInt ? Math.round((val * 100) / total) : Math.round((val * 10000) / total) / 100; // with 2 decimals
|
|
99
|
+
}
|
|
100
|
+
export function amountToDegree(val, total) {
|
|
101
|
+
// In a circle of {total}, determine degrees of slice {val}
|
|
102
|
+
return (val * 360) / total;
|
|
103
|
+
}
|
|
104
|
+
export function toFixed(number) {
|
|
105
|
+
return parseFloat((Math.floor(number * 100) / 100).toFixed(2));
|
|
106
|
+
}
|
|
107
|
+
export function polarToCartesian(half, radius, startAngle, endAngle) {
|
|
108
|
+
var x = toFixed(half + half * radius * Math.cos((Math.PI * startAngle) / 180));
|
|
109
|
+
var y = toFixed(half + half * radius * Math.sin((Math.PI * startAngle) / 180));
|
|
110
|
+
if (endAngle !== undefined) {
|
|
111
|
+
// if a 2nd angle value was passed, return 2 pairs of coords
|
|
112
|
+
var x2 = toFixed(half + half * radius * Math.cos((Math.PI * endAngle) / 180));
|
|
113
|
+
var y2 = toFixed(half + half * radius * Math.sin((Math.PI * endAngle) / 180));
|
|
114
|
+
return { x1: x, y1: y, x2, y2 };
|
|
115
|
+
}
|
|
116
|
+
return { x, y };
|
|
117
|
+
}
|
|
118
|
+
function getArc(radius, largeArcFlag, x, y, chartSize) {
|
|
119
|
+
var z = toFixed((chartSize / 2) * radius);
|
|
120
|
+
return `A ${z}, ${z} 0 ${largeArcFlag} ${toFixed(x)}, ${toFixed(y)}`;
|
|
121
|
+
}
|
|
122
|
+
function handleSliceKeyDown(ev) {
|
|
123
|
+
if (this.popoverEl && this.popoverEl.open && ev.key === "Enter") {
|
|
124
|
+
const popoverBtn = this.popoverEl.querySelector("button");
|
|
125
|
+
popoverBtn && popoverBtn.click();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export function handleSliceClick(ev, s) {
|
|
129
|
+
if (this.popoverEl && !this.isTabbing) {
|
|
130
|
+
s.coords = { x: ev.clientX, y: ev.clientY };
|
|
131
|
+
openPopover.call(this, s);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function handleSliceFocus(ev, s) {
|
|
135
|
+
if (this.popoverEl && this.isTabbing) {
|
|
136
|
+
s.coords = getPosition(ev.target);
|
|
137
|
+
openPopover.call(this, s);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export function handleChartKeydown(ev) {
|
|
141
|
+
switch (ev.key) {
|
|
142
|
+
// arrow up / left
|
|
143
|
+
case "ArrowUp":
|
|
144
|
+
case "ArrowLeft":
|
|
145
|
+
ev.preventDefault();
|
|
146
|
+
this.isTabbing = true; // shd already be true. just in case user clicked on chart then pressed an arrow key
|
|
147
|
+
focusPrevious.call(this);
|
|
148
|
+
break;
|
|
149
|
+
// arrow right / down
|
|
150
|
+
case "ArrowRight":
|
|
151
|
+
case "ArrowDown":
|
|
152
|
+
ev.preventDefault();
|
|
153
|
+
this.isTabbing = true; // shd already be true. just in case user clicked on chart then pressed an arrow key
|
|
154
|
+
focusNext.call(this);
|
|
155
|
+
break;
|
|
156
|
+
// tab
|
|
157
|
+
case "Tab":
|
|
158
|
+
exitChart.call(this);
|
|
159
|
+
break;
|
|
160
|
+
case "Escape":
|
|
161
|
+
this.popoverEl.open = false;
|
|
162
|
+
this.userIsNavigating = false;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export function openPopover(s) {
|
|
167
|
+
if (!!this.popoverEl && !!s.title && !!s.text) {
|
|
168
|
+
this.popoverEl.popoverTitle = s.title;
|
|
169
|
+
this.popoverEl.popoverText = s.text;
|
|
170
|
+
this.popoverEl.buttonText = s.buttonText;
|
|
171
|
+
this.popoverEl.coords = s.coords;
|
|
172
|
+
this.popoverEl.sliceRef = s.sliceRef;
|
|
173
|
+
window.setTimeout(() => {
|
|
174
|
+
if (this.popoverEl) {
|
|
175
|
+
this.popoverEl.open = true;
|
|
176
|
+
}
|
|
177
|
+
}, 30);
|
|
178
|
+
const debouncedClosePopover = debounce(async () => {
|
|
179
|
+
this.popoverEl.open = false;
|
|
180
|
+
}, 10);
|
|
181
|
+
// set up event listeners for scrolling
|
|
182
|
+
// to close popover on page scroll
|
|
183
|
+
document.addEventListener("scroll", () => {
|
|
184
|
+
debouncedClosePopover();
|
|
185
|
+
});
|
|
186
|
+
// ... and on parent scroll
|
|
187
|
+
const scrollableParent = findParentWithScrollbar(this.el);
|
|
188
|
+
if (!!scrollableParent) {
|
|
189
|
+
scrollableParent.addEventListener("scroll", () => {
|
|
190
|
+
debouncedClosePopover();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function focusNext() {
|
|
196
|
+
const activeEl = checkForActiveElInShadow(document.activeElement);
|
|
197
|
+
const index =
|
|
198
|
+
// if the active el is not in the array the first element gets focused
|
|
199
|
+
(this.sliceEls.indexOf(activeEl) + 1) % this.sliceEls.length;
|
|
200
|
+
focusSlice.call(this, index);
|
|
201
|
+
}
|
|
202
|
+
function focusPrevious() {
|
|
203
|
+
if (this.sliceEls) {
|
|
204
|
+
const activeEl = checkForActiveElInShadow(document.activeElement);
|
|
205
|
+
let index = this.sliceEls.indexOf(activeEl);
|
|
206
|
+
if (index === -1) {
|
|
207
|
+
// not in the array : focus the first slice
|
|
208
|
+
index = 0;
|
|
209
|
+
}
|
|
210
|
+
else if (index === 0) {
|
|
211
|
+
// first slice : focus the last slice
|
|
212
|
+
index = this.sliceEls.length - 1;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// anything else: focus previous
|
|
216
|
+
index -= 1;
|
|
217
|
+
}
|
|
218
|
+
focusSlice.call(this, index);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function focusSlice(index) {
|
|
222
|
+
if (this.sliceEls && this.el) {
|
|
223
|
+
this.userIsNavigating = true;
|
|
224
|
+
if (this.popoverEl) {
|
|
225
|
+
this.popoverEl.open = false;
|
|
226
|
+
}
|
|
227
|
+
this.el.tabIndex = -1;
|
|
228
|
+
// @ts-ignore
|
|
229
|
+
this.el.focusable = false; // for Edge
|
|
230
|
+
this.sliceEls.map((p) => {
|
|
231
|
+
p.tabIndex = -1;
|
|
232
|
+
// @ts-ignore
|
|
233
|
+
p.focusable = false; // for Edge
|
|
234
|
+
});
|
|
235
|
+
this.sliceEls[index].tabIndex = 0;
|
|
236
|
+
// @ts-ignore
|
|
237
|
+
this.sliceEls[index].focusable = true; // for Edge
|
|
238
|
+
this.sliceEls[index].focus();
|
|
239
|
+
window.setTimeout(() => {
|
|
240
|
+
if (this.popoverEl) {
|
|
241
|
+
this.popoverEl.open = true;
|
|
242
|
+
}
|
|
243
|
+
}, 10);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export function exitChart() {
|
|
247
|
+
this.sliceEls &&
|
|
248
|
+
this.sliceEls.map((p) => {
|
|
249
|
+
p.tabIndex = -1;
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
p.focusable = false; // for Edge
|
|
252
|
+
});
|
|
253
|
+
this.userIsNavigating = false;
|
|
254
|
+
// delay so that we can tab out of component before chart becomes focusable again
|
|
255
|
+
// and in case user was still pressing an arrow key when they pressed tab
|
|
256
|
+
window.setTimeout(() => {
|
|
257
|
+
if (this.el) {
|
|
258
|
+
this.el.tabIndex = 0;
|
|
259
|
+
// @ts-ignore
|
|
260
|
+
this.el.focusable = true; // for Edge
|
|
261
|
+
if (this.popoverEl) {
|
|
262
|
+
this.popoverEl.open = false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}, 100);
|
|
266
|
+
}
|
|
267
|
+
export async function getData(chartType) {
|
|
268
|
+
this.slicesData = [];
|
|
269
|
+
let acc = 0;
|
|
270
|
+
const children = Array.from(this.el.children);
|
|
271
|
+
this.total = children.reduce((total, slice) => (total += parseInt(slice.getAttribute("amount") || "0")), 0);
|
|
272
|
+
children.forEach((c, i) => {
|
|
273
|
+
const amount = parseInt(c.getAttribute("amount") || "0");
|
|
274
|
+
const perc = amountToPercent(amount, this.total, true);
|
|
275
|
+
// determine whether the slice is in a cluster of small values
|
|
276
|
+
// to avoid percentage text overlap for small values
|
|
277
|
+
const prev = children[i === 0 ? children.length - 1 : i - 1];
|
|
278
|
+
const prevPerc = amountToPercent(parseInt(prev.getAttribute("amount") || "0"), this.total, true);
|
|
279
|
+
const next = children[i === children.length - 1 ? 0 : i + 1];
|
|
280
|
+
const nextPerc = amountToPercent(parseInt(next.getAttribute("amount") || "0"), this.total, true);
|
|
281
|
+
const isSmall = perc < 4;
|
|
282
|
+
const prevIsSmall = prevPerc < 5;
|
|
283
|
+
const nextIsSmall = nextPerc < 5;
|
|
284
|
+
let inSmallCluster = isSmall && (prevIsSmall || nextIsSmall);
|
|
285
|
+
// because <1% slice percentage text has an additional character
|
|
286
|
+
// the inSmallCluster threshold needs to be widened for that slice only
|
|
287
|
+
const lessThanOnePerc = perc === 0 && amount > 0;
|
|
288
|
+
if (lessThanOnePerc && (nextPerc < 8 || prevPerc < 8)) {
|
|
289
|
+
inSmallCluster = true;
|
|
290
|
+
}
|
|
291
|
+
// for bar5, first color should be skipped unless notStartedColor is set to true
|
|
292
|
+
const ind = chartType === "bar5" ? (this.notStartedColor ? i : i + 1) : i;
|
|
293
|
+
const color = types[chartType].colors[ind];
|
|
294
|
+
const sliceData = {
|
|
295
|
+
amount: amount,
|
|
296
|
+
perc: perc,
|
|
297
|
+
legend: c.getAttribute("legend"),
|
|
298
|
+
color: color || "#d4d4d4",
|
|
299
|
+
offset: acc,
|
|
300
|
+
id: `${this.uid}-${i + 1}`,
|
|
301
|
+
title: c.getAttribute("popover-title"),
|
|
302
|
+
text: c.getAttribute("popover-text"),
|
|
303
|
+
buttonText: c.getAttribute("popover-button-text"),
|
|
304
|
+
sliceRef: c,
|
|
305
|
+
inSmallCluster: inSmallCluster,
|
|
306
|
+
};
|
|
307
|
+
acc += amount;
|
|
308
|
+
this.slicesData.push(sliceData);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
function getPathData(amount, offset, chartType) {
|
|
312
|
+
const startAngle = amountToDegree(offset, this.total) - 90; // start at noon, not at 3 o'clock
|
|
313
|
+
const activeAngle = (amount / this.total) * 360;
|
|
314
|
+
let endAngle = startAngle + activeAngle;
|
|
315
|
+
const largeArcFlagOuter = activeAngle > 180 ? "1 1" : "0 1";
|
|
316
|
+
const largeArcFlagInner = activeAngle > 180 ? "1 0" : "0 0";
|
|
317
|
+
const half = this.chartData.size / 2;
|
|
318
|
+
const innerRadius = this.chartData.thickness;
|
|
319
|
+
const outerRadius = 1;
|
|
320
|
+
const isHybridDoughnut = chartType === "doughnut0" || chartType === "doughnut";
|
|
321
|
+
const outerSeparatorOffset = 1.5;
|
|
322
|
+
const innerSeparatorOffset = isHybridDoughnut ? 2.25 : 3;
|
|
323
|
+
if (activeAngle === 360) {
|
|
324
|
+
// fix to avoid bad svg shape when the path goes all around (100%)
|
|
325
|
+
endAngle -= 0.01;
|
|
326
|
+
}
|
|
327
|
+
const outerCoords = polarToCartesian(half, outerRadius, startAngle + outerSeparatorOffset, // Addition for slice separator
|
|
328
|
+
endAngle);
|
|
329
|
+
const innerCoords = polarToCartesian(half, innerRadius, startAngle + innerSeparatorOffset, // Addition for slice separator
|
|
330
|
+
endAngle);
|
|
331
|
+
const moveTo = `M ${outerCoords.x1}, ${outerCoords.y1} `;
|
|
332
|
+
const arc1 = getArc(outerRadius, largeArcFlagOuter, outerCoords.x2, outerCoords.y2, this.chartData.size);
|
|
333
|
+
const line = ` L ${innerCoords.x2}, ${innerCoords.y2} `;
|
|
334
|
+
const arc2 = getArc(innerRadius, largeArcFlagInner, innerCoords.x1, innerCoords.y1, this.chartData.size);
|
|
335
|
+
return moveTo + arc1 + line + arc2 + " z";
|
|
336
|
+
}
|
|
337
|
+
function renderFilter() {
|
|
338
|
+
return (h("defs", null,
|
|
339
|
+
h("filter", { id: "wmHoverDropShadow" },
|
|
340
|
+
h("feGaussianBlur", { stdDeviation: "3" }),
|
|
341
|
+
h("feOffset", { result: "offsetblur" }),
|
|
342
|
+
h("feFlood", { "flood-color": "#333" }),
|
|
343
|
+
h("feComposite", { operator: "in", in2: "offsetblur" }),
|
|
344
|
+
h("feMerge", null,
|
|
345
|
+
h("feMergeNode", null),
|
|
346
|
+
h("feMergeNode", { in: "SourceGraphic" })))));
|
|
347
|
+
}
|
|
348
|
+
export function renderDoughnut(chartType) {
|
|
349
|
+
const outerSize = this.chartData.size + this.chartData.padding;
|
|
350
|
+
const isHybridDoughnut = chartType === "doughnut0" || chartType === "doughnut";
|
|
351
|
+
return (h("div", { class: "chart-wrapper doughnut-wrapper" },
|
|
352
|
+
h("svg", { width: outerSize + "px", height: outerSize + "px", id: `graphic-${this.uid}`, class: "doughnut-svg" },
|
|
353
|
+
renderFilter(),
|
|
354
|
+
this.slicesData.map((s) => renderPath.call(this, s, chartType)),
|
|
355
|
+
isHybridDoughnut ? (h("text", { class: "value", x: "50%", y: "50%", "font-size": "1.5rem", "font-weight": "500", "text-anchor": "middle", "dominant-baseline": "middle" }, amountToPercent(this.slicesData[0].amount, this.total, true) + "%")) : (h("g", { transform: `translate(${this.chartData.padding / 2}, ${this.chartData.padding / 2})`, "text-anchor": "middle", "dominant-baseline": "middle" }, this.slicesData.map((s) => (s.amount > 0 ? renderDoughnutText.call(this, s) : "")))))));
|
|
356
|
+
}
|
|
357
|
+
function renderPath(s, chartType) {
|
|
358
|
+
return (h("g", { transform: `translate(${this.chartData.padding / 2}, ${this.chartData.padding / 2})` },
|
|
359
|
+
h("path", { id: s.id, class: "segment doughnut-segment", fill: s.amount ? s.color : "transparent", d: getPathData.call(this, s.amount, s.offset, chartType), onClick: (ev) => handleSliceClick.call(this, ev, s), onFocus: (ev) => handleSliceFocus.call(this, ev, s), onKeyDown: (ev) => handleSliceKeyDown.call(this, ev), role: "img", "aria-label": s.legend })));
|
|
360
|
+
}
|
|
361
|
+
function renderDoughnutText(s) {
|
|
362
|
+
if (!s.inSmallCluster) {
|
|
363
|
+
const arcMiddle = amountToDegree(s.offset + s.amount / 2, this.total);
|
|
364
|
+
let { x, y } = polarToCartesian(this.chartData.size / 2, 1.4, arcMiddle - 90);
|
|
365
|
+
return (h("text", { class: "value", x: x + "px", y: y + "px" }, `${s.perc > 0 ? s.perc : "<1"}%`));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
export function renderBar(chartType) {
|
|
369
|
+
const isHybridBar = chartType === "bar1" || chartType === "bar";
|
|
370
|
+
return (h("div", { class: "chart-wrapper bar-wrapper" },
|
|
371
|
+
isHybridBar ? (h("div", { class: "single-perc" }, amountToPercent(this.slicesData[0].amount, this.total, true) + "%")) : (""),
|
|
372
|
+
this.chartType === "bar3" && this.drawAxis(),
|
|
373
|
+
h("div", { class: {
|
|
374
|
+
"inner-bar-wrapper": true,
|
|
375
|
+
"show-values": this.tempValueFormat === "percentage" || this.tempValueFormat === "amount",
|
|
376
|
+
} },
|
|
377
|
+
!isHybridBar ? (h("div", { class: "values" }, this.slicesData.map((s, idx) => (s.perc > 0 ? this.renderBarText(s, idx) : "")))) : (""),
|
|
378
|
+
h("div", { class: "bar-segments-wrapper" }, this.slicesData.map((s, idx) => renderBarSegment.call(this, s, idx))),
|
|
379
|
+
isHybridBar ? renderCompletionMessage.call(this) : "")));
|
|
380
|
+
}
|
|
381
|
+
function renderBarSegment(s, idx) {
|
|
382
|
+
const isLastSlice = idx !== this.slicesData.length - 1;
|
|
383
|
+
const width = `calc(${amountToPercent(s.amount, this.total, false)}%${isLastSlice ? " - 2px" : ""})`;
|
|
384
|
+
return (h("div", { class: `segment bar-segment ${amountToPercent(s.amount, this.total, false) === 0 ? "zero" : ""}`, style: {
|
|
385
|
+
backgroundColor: s.color,
|
|
386
|
+
width: width,
|
|
387
|
+
}, onClick: (ev) => handleSliceClick.call(this, ev, s), onFocus: (ev) => handleSliceFocus.call(this, ev, s), onKeyDown: (ev) => handleSliceKeyDown.call(this, ev) },
|
|
388
|
+
h("span", { class: "sr-only" }, s.legend)));
|
|
389
|
+
}
|
|
390
|
+
export function renderLegend() {
|
|
391
|
+
// legend is hidden for bar1 type regardless of showLegend value
|
|
392
|
+
if (this.showLegend) {
|
|
393
|
+
const hasCluster = this.slicesData.reduce((hasCluster, cur) => (hasCluster = cur.inSmallCluster ? true : hasCluster), false);
|
|
394
|
+
return (h("div", { class: "legend-wrapper" },
|
|
395
|
+
h("div", { class: `legend ${this.mode === "bar" ? "--top" : "--bottom"}`, "aria-hidden": "true" }, this.total > 0
|
|
396
|
+
? this.slicesData.map((s) => {
|
|
397
|
+
// when both legend and amount are omitted, the legend is not shown for that particular option (it's been deactivated by the user)
|
|
398
|
+
if (!!s.amount || !!s.legend) {
|
|
399
|
+
return (h("div", { class: "legend-item" },
|
|
400
|
+
h("div", { class: "legend-color", style: { "background-color": s.color } }),
|
|
401
|
+
h("div", { class: "legend-text" }, s.legend)));
|
|
402
|
+
}
|
|
403
|
+
})
|
|
404
|
+
: ""),
|
|
405
|
+
!this.chartData.isBar && hasCluster ? (h("div", { class: "cluster-warning" },
|
|
406
|
+
intl.formatMessage({
|
|
407
|
+
id: "chart.hiddenPercentages",
|
|
408
|
+
defaultMessage: "Percentages smaller than 5% are not shown when too close to each other.",
|
|
409
|
+
}),
|
|
410
|
+
h("br", null),
|
|
411
|
+
intl.formatMessage({
|
|
412
|
+
id: "chart.clickToSeeDetails",
|
|
413
|
+
defaultMessage: "Click or use arrow keys to see details.",
|
|
414
|
+
}))) : ("")));
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
export function renderCompletionMessage() {
|
|
418
|
+
if (this.completionMessage) {
|
|
419
|
+
return h("div", { class: "completion-message" }, this.completionMessage);
|
|
420
|
+
}
|
|
421
|
+
}
|