visualifyjs 2.5.3-2.dev → 3.0.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.
Files changed (252) hide show
  1. package/.claude/mem/TIMELINE.md +36 -0
  2. package/.claude/mem/notes/2026-02-11-3d-visualization-docs-fix-external-script-solution.md +24 -0
  3. package/.claude/mem/notes/2026-02-11-3d-visualization-docs-fix-session-summary.md +43 -0
  4. package/.claude/mem/notes/2026-02-11-cli-fix-editor-command-alias.md +26 -0
  5. package/.claude/mem/notes/2026-02-11-phase-3-developer-experience-completed.md +51 -0
  6. package/.claude/mem/notes/2026-02-11-phase-4-web-workers-implementation-complete.md +59 -0
  7. package/.claude/mem/notes/2026-02-11-visualify-phase-2-3d-visualization-complete.md +50 -0
  8. package/.claude/mem/notes/2026-02-11-visualify-phase-2-committed-ready-for-phase-3.md +33 -0
  9. package/.claude/mem/notes/2026-02-11-visualify-phase-3-complete-developer-experience.md +52 -0
  10. package/.claude/mem/notes/2026-02-11-visualify-repository-cleanup-complete.md +28 -0
  11. package/.claude/mem/notes/2026-02-18-codebase-cleanup-docsify-plugin-documentation.md +37 -0
  12. package/.claude/mem/notes/2026-02-19-css-grid-layout-fix-displaycontents-on-vcontroller.md +18 -0
  13. package/.claude/mem/notes/2026-02-19-docsify-plugin-fixes-latex-and-visualify-code-bloc.md +26 -0
  14. package/.claude/mem/notes/2026-02-19-page-mode-docs-update-decisions.md +23 -0
  15. package/.claude/mem/notes/2026-02-19-react-context-infinite-re-render-loop-fix-pattern.md +31 -0
  16. package/.claude/mem/notes/2026-02-19-version-300-bump-and-build-fixes.md +32 -0
  17. package/.claude/mem/notes/2026-02-19-visualify-build-deployment-architecture-bug-fixes.md +25 -0
  18. package/.claude/mem/notes/2026-02-19-visualify-dist-iife-self-contained-build-config.md +30 -0
  19. package/.claude/mem/notes/2026-02-19-visualify-infinite-loop-i18n-fixes.md +31 -0
  20. package/.claude/mem/notes/2026-02-19-visualify-v3-bundle-splitting-docs-restructuring.md +32 -0
  21. package/.claude/mem/notes/2026-02-20-bundle-externalization-final-architecture.md +29 -0
  22. package/.claude/mem/notes/2026-02-20-chromium-page-fix-unstable-keys-and-double-event-b.md +27 -0
  23. package/.claude/mem/notes/2026-02-20-console-cleanup-bundle-optimization-commit.md +20 -0
  24. package/.claude/mem/notes/2026-02-20-dotbio-dot-plot-fix-useeffect-dependency.md +21 -0
  25. package/.claude/mem/notes/2026-02-20-public-folder-cleanup-and-readme-rewrite.md +25 -0
  26. package/.claude/mem/notes/2026-02-20-v300-release-and-beta-channel-strategy.md +29 -0
  27. package/.claude/mem/notes/2026-02-20-visium-background-image-unknown-legend-fix.md +19 -0
  28. package/.claude/mem/notes/2026-02-20-visualify-cdn-loader-bundle-externalization.md +34 -0
  29. package/.claude/mem/sessions/session-2026-02-20-031524.md +54 -0
  30. package/.claude/settings.local.json +21 -0
  31. package/.github/workflows/static.yml.bak +51 -51
  32. package/.sisyphus/boulder.json +65 -0
  33. package/.sisyphus/plans/phase-4-advanced-optimizations.md +217 -0
  34. package/LICENSE +674 -674
  35. package/README.md +94 -59
  36. package/config-overrides.js +31 -31
  37. package/dist/stats.html +4949 -0
  38. package/dist/visualify-3d.esm.js +1 -0
  39. package/dist/visualify-3d.js +1 -0
  40. package/dist/visualify-core.esm.js +1 -0
  41. package/dist/visualify-core.js +1 -0
  42. package/dist/visualify-docs.esm.js +1 -0
  43. package/dist/visualify-docs.js +1 -0
  44. package/dist/visualify-loader.js +1 -0
  45. package/dist/visualify-pages.esm.js +1 -0
  46. package/dist/visualify-pages.js +1 -0
  47. package/dist/visualify-portal.esm.js +1 -0
  48. package/dist/visualify-portal.js +1 -0
  49. package/dist/visualify-shared.js +26571 -0
  50. package/dist/visualify.js +1 -188
  51. package/docs/CHANGELOG.md +148 -0
  52. package/docs/cli/commands.md +513 -0
  53. package/docs/configuration/visualify-json.md +474 -0
  54. package/docs/docs/3d-visualization.md +374 -0
  55. package/docs/docs/CLI.md +303 -34
  56. package/docs/docs/README.md +65 -65
  57. package/docs/docs/Rechart/bar.md +190 -190
  58. package/docs/docs/Rechart/funnel.md +241 -241
  59. package/docs/docs/Rechart/line.md +355 -355
  60. package/docs/docs/Rechart/pie.md +225 -225
  61. package/docs/docs/Rechart/radar.md +253 -253
  62. package/docs/docs/Rechart/scatter.md +298 -298
  63. package/docs/docs/_404.md +51 -51
  64. package/docs/docs/_coverpage.md +11 -11
  65. package/docs/docs/_sidebar.md +54 -44
  66. package/docs/docs/components/dotBio.md +87 -34
  67. package/docs/docs/components/echart.md +171 -82
  68. package/docs/docs/components/html.md +61 -34
  69. package/docs/docs/components/macaron.md +156 -145
  70. package/docs/docs/components/markdown.md +42 -0
  71. package/docs/docs/components/more.md +183 -142
  72. package/docs/docs/components/plotly.md +132 -62
  73. package/docs/docs/components/scatterL.md +171 -70
  74. package/docs/docs/components/visium.md +112 -57
  75. package/docs/docs/configuration.md +121 -121
  76. package/docs/docs/deploy.md +31 -31
  77. package/docs/docs/docsify-plugin.md +655 -0
  78. package/docs/docs/hmr.md +165 -0
  79. package/docs/docs/i18n.md +332 -0
  80. package/docs/docs/log.md +30 -9
  81. package/docs/docs/more-pages.md +23 -23
  82. package/docs/docs/quickstart.md +148 -124
  83. package/docs/docs/rechart-attributes.md +74 -74
  84. package/docs/docs/rechart-basic-usage.md +160 -162
  85. package/docs/docs/theme.md +5 -5
  86. package/docs/docs/typescript.md +306 -0
  87. package/docs/docs/visual-editor.md +359 -0
  88. package/docs/index.html +85 -71
  89. package/docs/manifest.json +23 -23
  90. package/docs/migration/v3-migration.md +392 -0
  91. package/docs/static/css/fluff-stuff.css +169 -169
  92. package/docs/static/css/font-awesome.min.css +4 -4
  93. package/docs/static/css/visualify.css +6 -25
  94. package/docs/static/js/3d-viz-examples.js +181 -0
  95. package/docs/static/js/configuration.js +630 -448
  96. package/docs/static/js/visualify.js +1 -188
  97. package/package.json +106 -84
  98. package/rollup.config.mjs +766 -76
  99. package/src/_css/404.css +115 -115
  100. package/src/_css/App.css +37 -37
  101. package/src/_css/autoSuggestion.css +26 -26
  102. package/src/_css/circular-progress.css +32 -32
  103. package/src/_css/index.css +36 -36
  104. package/src/_css/modern.css +350 -25
  105. package/src/_media/corner.svg +8 -8
  106. package/src/_media/download.svg +3 -3
  107. package/src/_media/logo.svg +14 -14
  108. package/src/_test/App.test.js +15 -15
  109. package/src/_utils/reportWebVitals.js +13 -13
  110. package/src/a11y/README.md +177 -0
  111. package/src/a11y/aria-labels.js +339 -0
  112. package/src/a11y/color-contrast.js +535 -0
  113. package/src/a11y/index.js +197 -0
  114. package/src/a11y/keyboard-nav.js +523 -0
  115. package/src/a11y/styles.css +165 -0
  116. package/src/cli/commands/dev.js +214 -0
  117. package/src/cli/commands/docs.js +521 -0
  118. package/src/cli/commands/edit.js +379 -0
  119. package/src/cli/commands/init.js +213 -0
  120. package/src/cli/commands/portal.js +236 -0
  121. package/src/cli/dev-server.js +530 -0
  122. package/src/cli/hmr.js +456 -0
  123. package/src/cli/index.js +180 -0
  124. package/src/cli/utils/config.js +207 -0
  125. package/src/cli/utils/logger.js +241 -0
  126. package/src/config/defaults.ts +122 -0
  127. package/src/config/index.ts +72 -0
  128. package/src/config/loader.ts +478 -0
  129. package/src/config/schema.ts +227 -0
  130. package/src/config/validator.ts +337 -0
  131. package/src/core/appContext.js +34 -27
  132. package/src/core/components/Bar.js +383 -0
  133. package/src/core/components/Bar3D.js +473 -0
  134. package/src/core/components/LargeDatasetChart.js +296 -0
  135. package/src/core/components/Line3D.js +310 -0
  136. package/src/core/components/Scatter.js +392 -188
  137. package/src/core/components/Scatter3D.js +455 -0
  138. package/src/core/components/ScatterBio.js +601 -572
  139. package/src/core/components/Surface3D.js +326 -0
  140. package/src/core/components/ThreeCustom.js +648 -0
  141. package/src/core/components/ThreeScene.js +459 -0
  142. package/src/core/components/VisiumPlot.js +191 -165
  143. package/src/core/components/browser.js +42 -42
  144. package/src/core/components/dotplot.js +413 -413
  145. package/src/core/components/html.js +29 -29
  146. package/src/core/components/list.js +178 -178
  147. package/src/core/components/macaron.js +206 -201
  148. package/src/core/components/markdown.js +56 -56
  149. package/src/core/components/parser.scatterBio.js +582 -587
  150. package/src/core/components/ratio.js +82 -80
  151. package/src/core/components/scatterL.js +206 -173
  152. package/src/core/components/searchbar.js +156 -131
  153. package/src/core/components/selection.js +310 -193
  154. package/src/core/components/timeline.js +236 -281
  155. package/src/core/components/visium.js +114 -97
  156. package/src/core/data-processor.js +413 -0
  157. package/src/core/fetch/condfetch.js +82 -82
  158. package/src/core/fetch/fetch.js +92 -92
  159. package/src/core/fetch/json.js +29 -29
  160. package/src/core/fetch/vfetch.js +42 -42
  161. package/src/core/hmr-client.js +724 -0
  162. package/src/core/liveEditor.js +44 -44
  163. package/src/core/modules/codeEditorWithPreview.js +104 -104
  164. package/src/core/modules/echarts/common.js +20 -20
  165. package/src/core/modules/echarts/gl.js +228 -0
  166. package/src/core/modules/echarts/presetHandler.js +41 -41
  167. package/src/core/modules/echarts/presets/esodev.chromium.js +172 -172
  168. package/src/core/modules/echarts/presets/esodev.codex.js +130 -130
  169. package/src/core/modules/echarts/presets/esodev.visium.js +123 -123
  170. package/src/core/modules/echarts/presets/mmtrbc.js +186 -186
  171. package/src/core/modules/echarts.js +70 -71
  172. package/src/core/modules/echartsUtils.js +43 -43
  173. package/src/core/modules/echartswitcher.js +227 -152
  174. package/src/core/modules/replotly/presetHandler.js +24 -24
  175. package/src/core/modules/replotly/presets/minimum.js +18 -18
  176. package/src/core/modules/replotly/presets/mmtrbc.dot.js +114 -114
  177. package/src/core/modules/replotly/presets/mmtrbc.violin.js +100 -100
  178. package/src/core/modules/replotly.js +74 -71
  179. package/src/core/modules/threejs/Camera.js +373 -0
  180. package/src/core/modules/threejs/Lighting.js +459 -0
  181. package/src/core/modules/threejs/Renderer.js +364 -0
  182. package/src/core/modules/threejs/Scene.js +266 -0
  183. package/src/core/modules/threejs/index.js +155 -0
  184. package/src/core/pages/404.js +50 -50
  185. package/src/core/pages/error.js +27 -27
  186. package/src/core/pages/jsonPage.js +62 -62
  187. package/src/core/pages/loading.js +44 -44
  188. package/src/core/parser/echart.data.js +204 -183
  189. package/src/core/parser/echart.features.js +125 -125
  190. package/src/core/parser/echart.general.js +147 -147
  191. package/src/core/parser/echart.hilbert.js +57 -57
  192. package/src/core/parser/echart.parser.js +210 -210
  193. package/src/core/parser/echart.series.js +67 -67
  194. package/src/core/parser/echart.types.js +76 -76
  195. package/src/core/parser/plotly.config.js +10 -10
  196. package/src/core/parser/plotly.data.js +132 -132
  197. package/src/core/parser/plotly.layout.js +9 -9
  198. package/src/core/parser/plotly.violin.js +18 -18
  199. package/src/core/recharts.js +361 -62
  200. package/src/core/router/alias.js +49 -49
  201. package/src/core/router/jsonRouter.js +31 -31
  202. package/src/core/themes/modern.js +32 -32
  203. package/src/core/themes/themeSelector.js +33 -33
  204. package/src/core/visualify.js +213 -47
  205. package/src/core/widgets/circularProgress.js +23 -23
  206. package/src/core/widgets/controller.js +116 -83
  207. package/src/core/widgets/errorBoundary.js +36 -36
  208. package/src/core/widgets/footer.js +185 -177
  209. package/src/core/widgets/header.js +238 -234
  210. package/src/core/widgets/layout/Grid.js +31 -31
  211. package/src/core/widgets/layout.js +36 -36
  212. package/src/core/widgets/mapping.js +56 -42
  213. package/src/core/workers/data-worker.js +349 -0
  214. package/src/core/workers/worker-pool.js +396 -0
  215. package/src/docsify/bundle.js +215 -0
  216. package/src/docsify/markdown.js +271 -0
  217. package/src/docsify/plugin.js +268 -0
  218. package/src/editor/README.md +172 -0
  219. package/src/editor/components/ChartBuilder.jsx +341 -0
  220. package/src/editor/components/ChartTypeSidebar.jsx +91 -0
  221. package/src/editor/components/Editor.jsx +367 -0
  222. package/src/editor/components/Preview.jsx +446 -0
  223. package/src/editor/components/PropertyPanel.jsx +468 -0
  224. package/src/editor/components/StatusBar.jsx +85 -0
  225. package/src/editor/context/EditorContext.js +248 -0
  226. package/src/editor/hooks/useDebounce.js +32 -0
  227. package/src/editor/index.js +315 -0
  228. package/src/editor/styles/editor.css +637 -0
  229. package/src/editor/utils/chartValidator.js +263 -0
  230. package/src/entries/charts3d.js +70 -0
  231. package/src/entries/core.js +78 -0
  232. package/src/entries/docs.js +154 -0
  233. package/src/entries/pages.js +93 -0
  234. package/src/entries/portal.js +204 -0
  235. package/src/entries/shared.js +50 -0
  236. package/src/i18n/formatters.js +455 -0
  237. package/src/i18n/index.js +169 -0
  238. package/src/i18n/locales/ar.json +137 -0
  239. package/src/i18n/locales/de.json +137 -0
  240. package/src/i18n/locales/en.json +137 -0
  241. package/src/i18n/locales/es.json +137 -0
  242. package/src/i18n/locales/he.json +137 -0
  243. package/src/i18n/locales/zh.json +137 -0
  244. package/src/i18n/rtl.css +183 -0
  245. package/src/index.js +82 -62
  246. package/src/loader.js +103 -0
  247. package/src/setupTests.js +5 -5
  248. package/tsconfig.json +51 -0
  249. package/types/charts.d.ts +569 -0
  250. package/types/components.d.ts +441 -0
  251. package/types/config.d.ts +199 -0
  252. package/types/index.d.ts +353 -0
@@ -1,183 +1,204 @@
1
- /*
2
- * @Author : Lihao leolihao@arizona.edu
3
- * @Date : 2023-12-02 16:52:58
4
- * @FilePath : /visualifyjs/src/core/parser/echart.data.js
5
- * @Description :
6
- * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
- */
8
- import { getArrayEl, _handleSeries } from './echart.series';
9
- import {
10
- _parsePeakvalley,
11
- _parseMarkArea,
12
- _parseMarkLine,
13
- } from './echart.features';
14
-
15
- const _parser_data = (options = {}, preset = {}) => {
16
- // Parse the custom options
17
- const parsedOptions = {
18
- ...preset,
19
- yAxis: { ...preset.yAxis },
20
- xAxis: { ...preset.xAxis },
21
- legend: { ...preset.legend },
22
- title: { ...preset.title },
23
- tooltip: { ...preset.tooltip },
24
- // ... other default settings for charts
25
- series: [],
26
- };
27
-
28
- // Initialize totalValues array if percentage mode is active
29
- let totalValues = options.percentage
30
- ? new Array(options.xAxis.length).fill(0)
31
- : [];
32
-
33
- // calculate total values if in percentage mode
34
- if (options.percentage && options.data) {
35
- Object.entries(options.data).forEach(([_, data]) => {
36
- data.forEach((value, idx) => {
37
- totalValues[idx] += value;
38
- });
39
- });
40
- }
41
-
42
- if (options.data && typeof options.data === 'object') {
43
- parsedOptions.series = Object.entries(options.data).map(
44
- ([name, data], index) => {
45
- let seriesObject = {
46
- name,
47
- type: getArrayEl(options.type, index),
48
- data,
49
- ...(options.markArea && {
50
- markArea: _parseMarkArea(options.markArea, index),
51
- }),
52
- ...(options.markLine && {
53
- markLine: _parseMarkLine(options.markLine, index),
54
- }),
55
- ...(options.symbol && {
56
- symbol: getArrayEl(options.symbol, index),
57
- }),
58
- ...(options.symbolSize && {
59
- symbolSize: getArrayEl(options.symbolSize, index),
60
- }),
61
- ...(options.stack && {
62
- stack: options.stack.includes(name)
63
- ? 'total'
64
- : getArrayEl(options.stack, index),
65
- }),
66
- ...(options.emphasis && {
67
- emphasis: getArrayEl(options.emphasis, index),
68
- }),
69
- };
70
-
71
- if (
72
- options.percentage &&
73
- (options.type === 'bar' || options.type === 'line')
74
- ) {
75
- seriesObject.data = seriesObject.data.map(
76
- (value, idx) => (value / totalValues[idx]) * 100,
77
- );
78
- seriesObject.stack = 'total';
79
- }
80
-
81
- if (options.waterfall) {
82
- if (name === 'Placeholder' || name === options.waterfall) {
83
- seriesObject.itemStyle = {
84
- borderColor: 'transparent',
85
- color: 'transparent',
86
- };
87
- seriesObject = {
88
- ...seriesObject,
89
- emphasis: {
90
- ...seriesObject?.emphasis,
91
- itemStyle: {
92
- borderColor: 'transparent',
93
- color: 'transparent',
94
- },
95
- },
96
- };
97
- }
98
- }
99
-
100
- _parsePeakvalley(options, seriesObject);
101
-
102
- _handleSeries(options, seriesObject, index);
103
-
104
- return seriesObject;
105
- },
106
- );
107
- }
108
-
109
- if (
110
- (Array.isArray(options.type) && options.type.includes('radar')) ||
111
- options.type === 'radar'
112
- )
113
- parsedOptions.radar = options.radar;
114
-
115
- // Modify yAxis for percentage display
116
- if (options.percentage) {
117
- parsedOptions.yAxis = {
118
- ...parsedOptions.yAxis,
119
- axisLabel: { formatter: '{value}%' },
120
- max: 100,
121
- };
122
-
123
- parsedOptions.tooltip = {
124
- trigger: 'axis',
125
- formatter: percentageTooltipFormatter,
126
- };
127
- }
128
-
129
- if (options.markArea || options.markLine) {
130
- parsedOptions.tooltip = {
131
- trigger: 'axis',
132
- axisPointer: {
133
- type: 'cross',
134
- },
135
- };
136
- }
137
-
138
- if (options.waterfall) {
139
- parsedOptions.legend = {
140
- ...parsedOptions.legend,
141
- data: parsedOptions.series
142
- .map((series) => series.name)
143
- .filter((name) => name !== 'Placeholder'),
144
- };
145
- parsedOptions.xAxis = {
146
- ...parsedOptions.xAxis,
147
- splitLine: { show: false },
148
- };
149
-
150
- parsedOptions.tooltip = {
151
- trigger: 'axis',
152
- axisPointer: {
153
- type: 'shadow',
154
- },
155
- formatter: function (params) {
156
- var tar = params[1];
157
- return (
158
- tar.name +
159
- '<br/>' +
160
- tar.marker +
161
- tar.seriesName +
162
- ' : ' +
163
- tar.value
164
- );
165
- },
166
- };
167
- }
168
-
169
- return parsedOptions;
170
- };
171
-
172
- export default _parser_data;
173
-
174
- export function percentageTooltipFormatter(params) {
175
- let total = params.reduce((sum, item) => sum + item.value, 0);
176
- let tooltipContent = params
177
- .map((item) => {
178
- let percentage = ((item.value / total) * 100).toFixed(2);
179
- return `${item.marker}${item.seriesName}: ${percentage}%`;
180
- })
181
- .join('<br/>');
182
- return `${params[0].axisValueLabel}<br/>${tooltipContent}`;
183
- }
1
+ /*
2
+ * @Author : Lihao leolihao@arizona.edu
3
+ * @Date : 2023-12-02 16:52:58
4
+ * @FilePath : /visualifyjs/src/core/parser/echart.data.js
5
+ * @Description :
6
+ * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
+ */
8
+ import { getArrayEl, _handleSeries } from './echart.series';
9
+ import {
10
+ _parsePeakvalley,
11
+ _parseMarkArea,
12
+ _parseMarkLine,
13
+ } from './echart.features';
14
+
15
+ const _parser_data = (options = {}, preset = {}) => {
16
+ // Parse the custom options
17
+ const parsedOptions = {
18
+ ...preset,
19
+ yAxis: { ...preset.yAxis },
20
+ xAxis: { ...preset.xAxis },
21
+ legend: { ...preset.legend },
22
+ title: { ...preset.title },
23
+ tooltip: { ...preset.tooltip },
24
+ // ... other default settings for charts
25
+ series: [],
26
+ };
27
+
28
+ // Initialize totalValues array if percentage mode is active
29
+ let totalValues = options.percentage
30
+ ? new Array(options.xAxis.length).fill(0)
31
+ : [];
32
+
33
+ // calculate total values if in percentage mode
34
+ if (options.percentage && options.data) {
35
+ Object.entries(options.data).forEach(([_, data]) => {
36
+ data.forEach((value, idx) => {
37
+ totalValues[idx] += value;
38
+ });
39
+ });
40
+ }
41
+
42
+ if (options.data && typeof options.data === 'object') {
43
+ // Detect structured format: { categories: [...], series: [{name, data}] }
44
+ const isStructuredFormat = options.data.series && Array.isArray(options.data.series);
45
+
46
+ if (isStructuredFormat) {
47
+ // Set xAxis categories if provided
48
+ if (options.data.categories) {
49
+ parsedOptions.xAxis = {
50
+ ...parsedOptions.xAxis,
51
+ data: options.data.categories,
52
+ };
53
+ }
54
+ }
55
+
56
+ // Normalize data entries: structured format vs flat object format
57
+ const dataEntries = isStructuredFormat
58
+ ? options.data.series.map((s, i) => [s.name || `Series ${i + 1}`, s.data || [], s])
59
+ : Object.entries(options.data).map(([name, data]) => [name, data, null]);
60
+
61
+ parsedOptions.series = dataEntries.map(
62
+ ([name, data, seriesMeta], index) => {
63
+ // Spread extra series-level properties from structured format (e.g., smooth, areaStyle)
64
+ const { name: _n, data: _d, ...extraSeriesProps } = seriesMeta || {};
65
+ let seriesObject = {
66
+ name,
67
+ type: getArrayEl(options.type, index),
68
+ data,
69
+ ...extraSeriesProps,
70
+ ...(options.markArea && {
71
+ markArea: _parseMarkArea(options.markArea, index),
72
+ }),
73
+ ...(options.markLine && {
74
+ markLine: _parseMarkLine(options.markLine, index),
75
+ }),
76
+ ...(options.symbol && {
77
+ symbol: getArrayEl(options.symbol, index),
78
+ }),
79
+ ...(options.symbolSize && {
80
+ symbolSize: getArrayEl(options.symbolSize, index),
81
+ }),
82
+ ...(options.stack && {
83
+ stack: options.stack.includes(name)
84
+ ? 'total'
85
+ : getArrayEl(options.stack, index),
86
+ }),
87
+ ...(options.emphasis && {
88
+ emphasis: getArrayEl(options.emphasis, index),
89
+ }),
90
+ };
91
+
92
+ if (
93
+ options.percentage &&
94
+ (options.type === 'bar' || options.type === 'line')
95
+ ) {
96
+ seriesObject.data = seriesObject.data.map(
97
+ (value, idx) => (value / totalValues[idx]) * 100,
98
+ );
99
+ seriesObject.stack = 'total';
100
+ }
101
+
102
+ if (options.waterfall) {
103
+ if (name === 'Placeholder' || name === options.waterfall) {
104
+ seriesObject.itemStyle = {
105
+ borderColor: 'transparent',
106
+ color: 'transparent',
107
+ };
108
+ seriesObject = {
109
+ ...seriesObject,
110
+ emphasis: {
111
+ ...seriesObject?.emphasis,
112
+ itemStyle: {
113
+ borderColor: 'transparent',
114
+ color: 'transparent',
115
+ },
116
+ },
117
+ };
118
+ }
119
+ }
120
+
121
+ _parsePeakvalley(options, seriesObject);
122
+
123
+ _handleSeries(options, seriesObject, index);
124
+
125
+ return seriesObject;
126
+ },
127
+ );
128
+ }
129
+
130
+ if (
131
+ (Array.isArray(options.type) && options.type.includes('radar')) ||
132
+ options.type === 'radar'
133
+ )
134
+ parsedOptions.radar = options.radar;
135
+
136
+ // Modify yAxis for percentage display
137
+ if (options.percentage) {
138
+ parsedOptions.yAxis = {
139
+ ...parsedOptions.yAxis,
140
+ axisLabel: { formatter: '{value}%' },
141
+ max: 100,
142
+ };
143
+
144
+ parsedOptions.tooltip = {
145
+ trigger: 'axis',
146
+ formatter: percentageTooltipFormatter,
147
+ };
148
+ }
149
+
150
+ if (options.markArea || options.markLine) {
151
+ parsedOptions.tooltip = {
152
+ trigger: 'axis',
153
+ axisPointer: {
154
+ type: 'cross',
155
+ },
156
+ };
157
+ }
158
+
159
+ if (options.waterfall) {
160
+ parsedOptions.legend = {
161
+ ...parsedOptions.legend,
162
+ data: parsedOptions.series
163
+ .map((series) => series.name)
164
+ .filter((name) => name !== 'Placeholder'),
165
+ };
166
+ parsedOptions.xAxis = {
167
+ ...parsedOptions.xAxis,
168
+ splitLine: { show: false },
169
+ };
170
+
171
+ parsedOptions.tooltip = {
172
+ trigger: 'axis',
173
+ axisPointer: {
174
+ type: 'shadow',
175
+ },
176
+ formatter: function (params) {
177
+ var tar = params[1];
178
+ return (
179
+ tar.name +
180
+ '<br/>' +
181
+ tar.marker +
182
+ tar.seriesName +
183
+ ' : ' +
184
+ tar.value
185
+ );
186
+ },
187
+ };
188
+ }
189
+
190
+ return parsedOptions;
191
+ };
192
+
193
+ export default _parser_data;
194
+
195
+ export function percentageTooltipFormatter(params) {
196
+ let total = params.reduce((sum, item) => sum + item.value, 0);
197
+ let tooltipContent = params
198
+ .map((item) => {
199
+ let percentage = ((item.value / total) * 100).toFixed(2);
200
+ return `${item.marker}${item.seriesName}: ${percentage}%`;
201
+ })
202
+ .join('<br/>');
203
+ return `${params[0].axisValueLabel}<br/>${tooltipContent}`;
204
+ }
@@ -1,125 +1,125 @@
1
- /*
2
- * @Author : Lihao leolihao@arizona.edu
3
- * @Date : 2023-12-03 13:01:48
4
- * @FilePath : /visualifyjs/src/core/parser/echart.features.js
5
- * @Description :
6
- * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
- */
8
-
9
- export function _parsePeakvalley(options, seriesObject) {
10
- if (options.valley || options.peak) {
11
- seriesObject.markPoint = {};
12
- seriesObject.markPoint.data = [];
13
- if (options.peak) {
14
- seriesObject.markPoint.data.push({
15
- type: 'max',
16
- name: 'Max',
17
- label: {
18
- formatter:
19
- typeof options.peak === 'string' ? options.peak : 'Max',
20
- },
21
- });
22
- }
23
- if (options.valley) {
24
- seriesObject.markPoint.data.push({
25
- type: 'min',
26
- name: 'Min',
27
- label: {
28
- formatter:
29
- typeof options.valley === 'string'
30
- ? options.valley
31
- : 'Min',
32
- },
33
- });
34
- }
35
- }
36
- }
37
-
38
- export function _parseMarkArea(markAreaOption, seriesIndex) {
39
- const markAreaOptions = {};
40
-
41
- const formatAreaData = (option) => {
42
- let areas = [];
43
-
44
- const processAxis = (axisData, axisName) => {
45
- if (Array.isArray(axisData)) {
46
- axisData.forEach((data) =>
47
- areas.push([
48
- { [axisName]: data.start, name: data.name },
49
- { [axisName]: data.end },
50
- ]),
51
- );
52
- } else {
53
- areas.push([
54
- { [axisName]: axisData.start, name: axisData.name },
55
- { [axisName]: axisData.end },
56
- ]);
57
- }
58
- };
59
-
60
- if (option.xAxis) {
61
- processAxis(option.xAxis, 'xAxis');
62
- }
63
- if (option.yAxis) {
64
- processAxis(option.yAxis, 'yAxis');
65
- }
66
-
67
- return areas;
68
- };
69
-
70
- let areaData = [];
71
- let selectedOption =
72
- Array.isArray(markAreaOption) && seriesIndex < markAreaOption.length
73
- ? markAreaOption[seriesIndex]
74
- : markAreaOption;
75
-
76
- areaData = formatAreaData(selectedOption);
77
- markAreaOptions.data = areaData;
78
-
79
- // Add emphasis and other additional properties
80
- Object.keys(selectedOption).forEach((key) => {
81
- if (key === 'data') {
82
- markAreaOptions[key] = markAreaOptions[key].concat(
83
- selectedOption[key],
84
- );
85
- } else if (key !== 'xAxis' && key !== 'yAxis') {
86
- markAreaOptions[key] = selectedOption[key];
87
- }
88
- });
89
-
90
- return markAreaOptions;
91
- }
92
-
93
- export function _parseMarkLine(markLineOption, seriesIndex) {
94
- const markLineOptions = {};
95
-
96
- let selectedOption =
97
- Array.isArray(markLineOption) && seriesIndex < markLineOption.length
98
- ? markLineOption[seriesIndex]
99
- : markLineOption;
100
-
101
- markLineOptions.emphasis = {
102
- lineStyle: {
103
- width: 5,
104
- type: 'solid',
105
- },
106
- };
107
-
108
- markLineOptions.blur = {
109
- lineStyle: {
110
- opacity: 0.5, // Example blur style
111
- },
112
- };
113
-
114
- markLineOptions.lineStyle = {
115
- type: 'dashed', // 'solid','dashed'
116
- width: 3,
117
- };
118
-
119
- // Add additional properties from markLineOption
120
- Object.keys(selectedOption).forEach((key) => {
121
- markLineOptions[key] = selectedOption[key];
122
- });
123
-
124
- return markLineOptions;
125
- }
1
+ /*
2
+ * @Author : Lihao leolihao@arizona.edu
3
+ * @Date : 2023-12-03 13:01:48
4
+ * @FilePath : /visualifyjs/src/core/parser/echart.features.js
5
+ * @Description :
6
+ * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
+ */
8
+
9
+ export function _parsePeakvalley(options, seriesObject) {
10
+ if (options.valley || options.peak) {
11
+ seriesObject.markPoint = {};
12
+ seriesObject.markPoint.data = [];
13
+ if (options.peak) {
14
+ seriesObject.markPoint.data.push({
15
+ type: 'max',
16
+ name: 'Max',
17
+ label: {
18
+ formatter:
19
+ typeof options.peak === 'string' ? options.peak : 'Max',
20
+ },
21
+ });
22
+ }
23
+ if (options.valley) {
24
+ seriesObject.markPoint.data.push({
25
+ type: 'min',
26
+ name: 'Min',
27
+ label: {
28
+ formatter:
29
+ typeof options.valley === 'string'
30
+ ? options.valley
31
+ : 'Min',
32
+ },
33
+ });
34
+ }
35
+ }
36
+ }
37
+
38
+ export function _parseMarkArea(markAreaOption, seriesIndex) {
39
+ const markAreaOptions = {};
40
+
41
+ const formatAreaData = (option) => {
42
+ let areas = [];
43
+
44
+ const processAxis = (axisData, axisName) => {
45
+ if (Array.isArray(axisData)) {
46
+ axisData.forEach((data) =>
47
+ areas.push([
48
+ { [axisName]: data.start, name: data.name },
49
+ { [axisName]: data.end },
50
+ ]),
51
+ );
52
+ } else {
53
+ areas.push([
54
+ { [axisName]: axisData.start, name: axisData.name },
55
+ { [axisName]: axisData.end },
56
+ ]);
57
+ }
58
+ };
59
+
60
+ if (option.xAxis) {
61
+ processAxis(option.xAxis, 'xAxis');
62
+ }
63
+ if (option.yAxis) {
64
+ processAxis(option.yAxis, 'yAxis');
65
+ }
66
+
67
+ return areas;
68
+ };
69
+
70
+ let areaData = [];
71
+ let selectedOption =
72
+ Array.isArray(markAreaOption) && seriesIndex < markAreaOption.length
73
+ ? markAreaOption[seriesIndex]
74
+ : markAreaOption;
75
+
76
+ areaData = formatAreaData(selectedOption);
77
+ markAreaOptions.data = areaData;
78
+
79
+ // Add emphasis and other additional properties
80
+ Object.keys(selectedOption).forEach((key) => {
81
+ if (key === 'data') {
82
+ markAreaOptions[key] = markAreaOptions[key].concat(
83
+ selectedOption[key],
84
+ );
85
+ } else if (key !== 'xAxis' && key !== 'yAxis') {
86
+ markAreaOptions[key] = selectedOption[key];
87
+ }
88
+ });
89
+
90
+ return markAreaOptions;
91
+ }
92
+
93
+ export function _parseMarkLine(markLineOption, seriesIndex) {
94
+ const markLineOptions = {};
95
+
96
+ let selectedOption =
97
+ Array.isArray(markLineOption) && seriesIndex < markLineOption.length
98
+ ? markLineOption[seriesIndex]
99
+ : markLineOption;
100
+
101
+ markLineOptions.emphasis = {
102
+ lineStyle: {
103
+ width: 5,
104
+ type: 'solid',
105
+ },
106
+ };
107
+
108
+ markLineOptions.blur = {
109
+ lineStyle: {
110
+ opacity: 0.5, // Example blur style
111
+ },
112
+ };
113
+
114
+ markLineOptions.lineStyle = {
115
+ type: 'dashed', // 'solid','dashed'
116
+ width: 3,
117
+ };
118
+
119
+ // Add additional properties from markLineOption
120
+ Object.keys(selectedOption).forEach((key) => {
121
+ markLineOptions[key] = selectedOption[key];
122
+ });
123
+
124
+ return markLineOptions;
125
+ }