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,44 +1,44 @@
1
- /*
2
- * @Author : Lihao leolihao@arizona.edu
3
- * @Date : 2023-12-01 22:51:45
4
- * @FilePath : /visualifyjs/src/core/liveEditor.js
5
- * @Description :
6
- * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
- */
8
- import React from 'react';
9
- import Recharts from './recharts';
10
- import { createRoot } from 'react-dom/client';
11
- import CodeEditorWithPreview from './modules/codeEditorWithPreview';
12
- import { VisualifyProvider } from './appContext';
13
- class LiveEditor extends Recharts {
14
- constructor(config) {
15
- super();
16
- this.config = config;
17
- }
18
-
19
- mount(selector) {
20
- const el =
21
- typeof selector === 'string'
22
- ? document.querySelector(selector)
23
- : selector;
24
-
25
- if (!el) {
26
- throw new Error(`Element not found with selector: ${selector}`);
27
- }
28
-
29
- try {
30
- // Assuming createRoot is imported from 'react-dom/client'
31
- const charts = createRoot(el);
32
- charts.render(
33
- <VisualifyProvider>
34
- <CodeEditorWithPreview config={this.config} />
35
- </VisualifyProvider>,
36
- );
37
- console.log('mounted ' + selector, el);
38
- } catch (e) {
39
- console.error('Error mounting chart:', e);
40
- }
41
- }
42
- }
43
-
44
- export default LiveEditor;
1
+ /*
2
+ * @Author : Lihao leolihao@arizona.edu
3
+ * @Date : 2023-12-01 22:51:45
4
+ * @FilePath : /visualifyjs/src/core/liveEditor.js
5
+ * @Description :
6
+ * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
+ */
8
+ import React from 'react';
9
+ import Recharts from './recharts';
10
+ import { createRoot } from 'react-dom/client';
11
+ import CodeEditorWithPreview from './modules/codeEditorWithPreview';
12
+ import { VisualifyProvider } from './appContext';
13
+ class LiveEditor extends Recharts {
14
+ constructor(config) {
15
+ super();
16
+ this.config = config;
17
+ }
18
+
19
+ mount(selector) {
20
+ const el =
21
+ typeof selector === 'string'
22
+ ? document.querySelector(selector)
23
+ : selector;
24
+
25
+ if (!el) {
26
+ throw new Error(`Element not found with selector: ${selector}`);
27
+ }
28
+
29
+ try {
30
+ // Assuming createRoot is imported from 'react-dom/client'
31
+ const charts = createRoot(el);
32
+ charts.render(
33
+ <VisualifyProvider>
34
+ <CodeEditorWithPreview config={this.config} />
35
+ </VisualifyProvider>,
36
+ );
37
+ console.log('mounted ' + selector, el);
38
+ } catch (e) {
39
+ console.error('Error mounting chart:', e);
40
+ }
41
+ }
42
+ }
43
+
44
+ export default LiveEditor;
@@ -1,104 +1,104 @@
1
- /*
2
- * @Author : Lihao leolihao@arizona.edu
3
- * @Date : 2023-12-01 22:17:15
4
- * @FilePath : /visualifyjs/src/core/modules/codeEditorWithPreview.js
5
- * @Description :
6
- * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
- */
8
- import React, { useState } from 'react';
9
- import AceEditor from 'react-ace';
10
- import EChartSwitcher from './echartswitcher';
11
- import 'ace-builds/src-noconflict/mode-javascript';
12
- import 'ace-builds/src-noconflict/theme-monokai';
13
-
14
- const CodeEditorWithPreview = ({ config }) => {
15
- const supportedThemes = ['', 'monokai'];
16
- const supportedMode = ['javascript'];
17
-
18
- const {
19
- theme = '',
20
- mode = 'javascript',
21
- width,
22
- height = '400px',
23
- title = 'Rechart Preview',
24
- editorProps = { $blockScrolling: true },
25
- } = config;
26
-
27
- if (!supportedThemes.includes(theme)) {
28
- throw new Error(
29
- `Theme '${theme}' not supported. Supported themes are: ${supportedThemes.join(
30
- ', ',
31
- )}`,
32
- );
33
- }
34
-
35
- if (!supportedMode.includes(mode)) {
36
- throw new Error(
37
- `Mode '${mode}' not supported. Supported modes are: ${supportedMode.join(
38
- ', ',
39
- )}`,
40
- );
41
- }
42
-
43
- const [code, setCode] = useState(config.code);
44
-
45
- // Function to evaluate the code and return the chart options
46
- const getChartOptions = () => {
47
- try {
48
- // eslint-disable-next-line no-new-func
49
- const func = new Function(code);
50
- return func()();
51
- } catch (error) {
52
- console.error('Error evaluating chart options:', error);
53
- return {};
54
- }
55
- };
56
-
57
- const blockStyles = {
58
- display: 'flex',
59
- justifyContent: 'space-between',
60
- };
61
- if (width) blockStyles.width = width;
62
-
63
- const editorStyles = {
64
- flexGrow: 1,
65
- border: '1px solid #ddd',
66
- borderRadius: '4px',
67
- marginBottom: '10px',
68
- width: '50%',
69
- };
70
-
71
- const editorTitleStyles = {
72
- backgroundColor: '#f4f4f4',
73
- padding: '10px',
74
- borderBottom: '1px solid #ddd',
75
- width: '100%',
76
- };
77
-
78
- return (
79
- <div style={blockStyles}>
80
- <div style={editorStyles}>
81
- <div style={editorTitleStyles}>{title}</div>
82
- <AceEditor
83
- mode={mode}
84
- theme={theme}
85
- value={code}
86
- onChange={setCode}
87
- name={title}
88
- editorProps={editorProps}
89
- width='100%'
90
- height={height}
91
- setOptions={{
92
- wrap: true,
93
- useWorker: false,
94
- }}
95
- />
96
- </div>
97
- <div style={{ width: '50%' }}>
98
- <EChartSwitcher props={{ config: getChartOptions() }} />
99
- </div>
100
- </div>
101
- );
102
- };
103
-
104
- export default CodeEditorWithPreview;
1
+ /*
2
+ * @Author : Lihao leolihao@arizona.edu
3
+ * @Date : 2023-12-01 22:17:15
4
+ * @FilePath : /visualifyjs/src/core/modules/codeEditorWithPreview.js
5
+ * @Description :
6
+ * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
+ */
8
+ import React, { useState } from 'react';
9
+ import AceEditor from 'react-ace';
10
+ import EChartSwitcher from './echartswitcher';
11
+ import 'ace-builds/src-noconflict/mode-javascript';
12
+ import 'ace-builds/src-noconflict/theme-monokai';
13
+
14
+ const CodeEditorWithPreview = ({ config }) => {
15
+ const supportedThemes = ['', 'monokai'];
16
+ const supportedMode = ['javascript'];
17
+
18
+ const {
19
+ theme = '',
20
+ mode = 'javascript',
21
+ width,
22
+ height = '400px',
23
+ title = 'Rechart Preview',
24
+ editorProps = { $blockScrolling: true },
25
+ } = config;
26
+
27
+ if (!supportedThemes.includes(theme)) {
28
+ throw new Error(
29
+ `Theme '${theme}' not supported. Supported themes are: ${supportedThemes.join(
30
+ ', ',
31
+ )}`,
32
+ );
33
+ }
34
+
35
+ if (!supportedMode.includes(mode)) {
36
+ throw new Error(
37
+ `Mode '${mode}' not supported. Supported modes are: ${supportedMode.join(
38
+ ', ',
39
+ )}`,
40
+ );
41
+ }
42
+
43
+ const [code, setCode] = useState(config.code);
44
+
45
+ // Function to evaluate the code and return the chart options
46
+ const getChartOptions = () => {
47
+ try {
48
+ // eslint-disable-next-line no-new-func
49
+ const func = new Function(code);
50
+ return func()();
51
+ } catch (error) {
52
+ console.error('Error evaluating chart options:', error);
53
+ return {};
54
+ }
55
+ };
56
+
57
+ const blockStyles = {
58
+ display: 'flex',
59
+ justifyContent: 'space-between',
60
+ };
61
+ if (width) blockStyles.width = width;
62
+
63
+ const editorStyles = {
64
+ flexGrow: 1,
65
+ border: '1px solid #ddd',
66
+ borderRadius: '4px',
67
+ marginBottom: '10px',
68
+ width: '50%',
69
+ };
70
+
71
+ const editorTitleStyles = {
72
+ backgroundColor: '#f4f4f4',
73
+ padding: '10px',
74
+ borderBottom: '1px solid #ddd',
75
+ width: '100%',
76
+ };
77
+
78
+ return (
79
+ <div style={blockStyles}>
80
+ <div style={editorStyles}>
81
+ <div style={editorTitleStyles}>{title}</div>
82
+ <AceEditor
83
+ mode={mode}
84
+ theme={theme}
85
+ value={code}
86
+ onChange={setCode}
87
+ name={title}
88
+ editorProps={editorProps}
89
+ width='100%'
90
+ height={height}
91
+ setOptions={{
92
+ wrap: true,
93
+ useWorker: false,
94
+ }}
95
+ />
96
+ </div>
97
+ <div style={{ width: '50%' }}>
98
+ <EChartSwitcher props={{ config: getChartOptions() }} />
99
+ </div>
100
+ </div>
101
+ );
102
+ };
103
+
104
+ export default CodeEditorWithPreview;
@@ -1,20 +1,20 @@
1
- /*
2
- * @Author : Lihao leolihao@arizona.edu
3
- * @Date : 2023-12-01 21:43:02
4
- * @FilePath : /visualifyjs/src/core/modules/echarts/common.js
5
- * @Description :
6
- * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
- */
8
- const minimumPreset = {
9
- title: {},
10
- tooltip: {},
11
- legend: {
12
- top: 25,
13
- },
14
- xAxis: {},
15
- yAxis: {},
16
- series: [],
17
- // ... other default settings for charts
18
- };
19
-
20
- export default minimumPreset;
1
+ /*
2
+ * @Author : Lihao leolihao@arizona.edu
3
+ * @Date : 2023-12-01 21:43:02
4
+ * @FilePath : /visualifyjs/src/core/modules/echarts/common.js
5
+ * @Description :
6
+ * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
+ */
8
+ const minimumPreset = {
9
+ title: {},
10
+ tooltip: {},
11
+ legend: {
12
+ top: 25,
13
+ },
14
+ xAxis: {},
15
+ yAxis: {},
16
+ series: [],
17
+ // ... other default settings for charts
18
+ };
19
+
20
+ export default minimumPreset;
@@ -0,0 +1,228 @@
1
+ /**
2
+ * ECharts GL Integration Module
3
+ * Provides lazy loading and WebGL support detection for 3D charts
4
+ * @module echarts/gl
5
+ */
6
+
7
+ import { toast } from 'react-toastify';
8
+
9
+ /**
10
+ * Checks if the browser supports WebGL
11
+ * @returns {boolean} True if WebGL is supported
12
+ */
13
+ export function isWebGLSupported() {
14
+ try {
15
+ const canvas = document.createElement('canvas');
16
+ const gl =
17
+ canvas.getContext('webgl2') ||
18
+ canvas.getContext('webgl') ||
19
+ canvas.getContext('experimental-webgl');
20
+ return !!gl;
21
+ } catch (e) {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Gets WebGL context information for debugging
28
+ * @returns {Object|null} WebGL context info or null if not supported
29
+ */
30
+ export function getWebGLInfo() {
31
+ try {
32
+ const canvas = document.createElement('canvas');
33
+ const gl =
34
+ canvas.getContext('webgl2') ||
35
+ canvas.getContext('webgl') ||
36
+ canvas.getContext('experimental-webgl');
37
+ if (!gl) return null;
38
+
39
+ return {
40
+ vendor: gl.getParameter(gl.VENDOR),
41
+ renderer: gl.getParameter(gl.RENDERER),
42
+ version: gl.getParameter(gl.VERSION),
43
+ shadingLanguageVersion: gl.getParameter(gl.SHADING_LANGUAGE_VERSION),
44
+ maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
45
+ maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS),
46
+ };
47
+ } catch (e) {
48
+ return null;
49
+ }
50
+ }
51
+
52
+ // Module cache for lazy loading
53
+ let echartsGLModule = null;
54
+ let loadingPromise = null;
55
+
56
+ /**
57
+ * Lazy loads ECharts GL module
58
+ * Only loads when 3D charts are actually rendered
59
+ * @returns {Promise<Object>} ECharts GL module
60
+ * @throws {Error} If WebGL is not supported or module fails to load
61
+ */
62
+ export async function loadEChartsGL() {
63
+ // Return cached module if available
64
+ if (echartsGLModule) {
65
+ return echartsGLModule;
66
+ }
67
+
68
+ // Return existing promise if already loading
69
+ if (loadingPromise) {
70
+ return loadingPromise;
71
+ }
72
+
73
+ // Check WebGL support before attempting to load
74
+ if (!isWebGLSupported()) {
75
+ const error = new Error(
76
+ 'WebGL is not supported in this browser. 3D charts require WebGL support.',
77
+ );
78
+ error.code = 'WEBGL_NOT_SUPPORTED';
79
+ throw error;
80
+ }
81
+
82
+ // Check if echarts-gl is already loaded globally (e.g., from CDN)
83
+ if (typeof window !== 'undefined' && window['echarts-gl']) {
84
+ echartsGLModule = window['echarts-gl'];
85
+ return Promise.resolve(echartsGLModule);
86
+ }
87
+
88
+ // Lazy load ECharts GL
89
+ loadingPromise = import('echarts-gl')
90
+ .then((module) => {
91
+ echartsGLModule = module;
92
+ return module;
93
+ })
94
+ .catch((error) => {
95
+ loadingPromise = null;
96
+ const loadError = new Error(
97
+ `Failed to load ECharts GL: ${error.message}`,
98
+ );
99
+ loadError.code = 'ECHARTS_GL_LOAD_ERROR';
100
+ loadError.originalError = error;
101
+ throw loadError;
102
+ });
103
+
104
+ return loadingPromise;
105
+ }
106
+
107
+ /**
108
+ * Preloads ECharts GL module in the background
109
+ * Useful for improving perceived performance when 3D charts are expected
110
+ */
111
+ export function preloadEChartsGL() {
112
+ if (!echartsGLModule && !loadingPromise && isWebGLSupported()) {
113
+ loadEChartsGL().catch(() => {
114
+ // Silently fail preload - actual error handling happens at render time
115
+ });
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Gets the current loading state of ECharts GL
121
+ * @returns {Object} Loading state information
122
+ */
123
+ export function getLoadingState() {
124
+ return {
125
+ isLoaded: !!echartsGLModule,
126
+ isLoading: !!loadingPromise,
127
+ isSupported: isWebGLSupported(),
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Displays a user-friendly error message for WebGL/3D chart errors
133
+ * @param {Error} error - The error object
134
+ * @param {Object} options - Display options
135
+ * @param {boolean} options.useToast - Whether to use toast notification (default: true)
136
+ * @param {string} options.fallbackMessage - Custom fallback message
137
+ */
138
+ export function display3DError(error, options = {}) {
139
+ const { useToast = true, fallbackMessage } = options;
140
+
141
+ let message =
142
+ fallbackMessage || 'Unable to display 3D chart. Please try a different browser.';
143
+
144
+ if (error.code === 'WEBGL_NOT_SUPPORTED') {
145
+ message =
146
+ 'Your browser does not support WebGL, which is required for 3D charts. ' +
147
+ 'Please use a modern browser like Chrome, Firefox, Safari, or Edge.';
148
+ } else if (error.code === 'ECHARTS_GL_LOAD_ERROR') {
149
+ message =
150
+ 'Failed to load 3D chart library. Please check your internet connection and try again.';
151
+ }
152
+
153
+ if (useToast && typeof toast !== 'undefined') {
154
+ toast.error(message, {
155
+ position: 'top-center',
156
+ autoClose: 5000,
157
+ hideProgressBar: false,
158
+ closeOnClick: true,
159
+ pauseOnHover: true,
160
+ draggable: true,
161
+ });
162
+ }
163
+
164
+ return message;
165
+ }
166
+
167
+ /**
168
+ * Cleanup function to dispose of WebGL resources
169
+ * Should be called when 3D chart components unmount
170
+ * @param {Object} chartInstance - ECharts instance
171
+ */
172
+ export function cleanupWebGL(chartInstance) {
173
+ if (!chartInstance) return;
174
+
175
+ try {
176
+ // Remove all event listeners
177
+ chartInstance.off();
178
+
179
+ // Dispose the chart instance
180
+ if (!chartInstance.isDisposed()) {
181
+ chartInstance.dispose();
182
+ }
183
+ } catch (error) {
184
+ // Silently handle cleanup errors
185
+ console.warn('Error during WebGL cleanup:', error);
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Hook for handling WebGL context loss
191
+ * @param {HTMLCanvasElement} canvas - The canvas element
192
+ * @param {Function} onRestore - Callback when context is restored
193
+ * @returns {Function} Cleanup function
194
+ */
195
+ export function handleWebGLContextLoss(canvas, onRestore) {
196
+ if (!canvas) return () => {};
197
+
198
+ const handleContextLost = (event) => {
199
+ event.preventDefault();
200
+ console.warn('WebGL context lost');
201
+ };
202
+
203
+ const handleContextRestored = () => {
204
+ console.info('WebGL context restored');
205
+ if (typeof onRestore === 'function') {
206
+ onRestore();
207
+ }
208
+ };
209
+
210
+ canvas.addEventListener('webglcontextlost', handleContextLost);
211
+ canvas.addEventListener('webglcontextrestored', handleContextRestored);
212
+
213
+ return () => {
214
+ canvas.removeEventListener('webglcontextlost', handleContextLost);
215
+ canvas.removeEventListener('webglcontextrestored', handleContextRestored);
216
+ };
217
+ }
218
+
219
+ export default {
220
+ isWebGLSupported,
221
+ getWebGLInfo,
222
+ loadEChartsGL,
223
+ preloadEChartsGL,
224
+ getLoadingState,
225
+ display3DError,
226
+ cleanupWebGL,
227
+ handleWebGLContextLoss,
228
+ };
@@ -1,41 +1,41 @@
1
- /*
2
- * @Author : Lihao leolihao@arizona.edu
3
- * @Date : 2023-12-02 21:36:01
4
- * @FilePath : /visualifyjs/src/core/modules/echarts/presetHandler.js
5
- * @Description :
6
- * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
- */
8
- // presetHandler.js
9
- import minimumPreset from './common';
10
- import mmtrbc from './presets/mmtrbc';
11
- import esodev_chromium from './presets/esodev.chromium';
12
- import esodev_codex from './presets/esodev.codex';
13
- import esodev_visium from './presets/esodev.visium';
14
-
15
- // Example embedded presets
16
- const embeddedPresets = {
17
- mmtrbc: mmtrbc,
18
- esodev_chromium: esodev_chromium,
19
- esodev_codex: esodev_codex,
20
- esodev_visium: esodev_visium,
21
- // 'presetName': { ...preset data... }
22
- // Define embedded presets here
23
- };
24
-
25
- // Function to fetch preset data from a URL
26
- export const fetchPresetFromURL = async (url) => {
27
- try {
28
- const response = await fetch(url);
29
- const data = await response.json();
30
- return data;
31
- } catch (error) {
32
- console.error('Error fetching preset from URL:', error);
33
- return null; // Return null or appropriate error handling
34
- }
35
- };
36
-
37
- // Function to get an embedded preset based on a string key
38
- export const getEmbeddedPreset = (presetKey) => {
39
- // Return minimumPreset if preset not found
40
- return embeddedPresets[presetKey] || minimumPreset;
41
- };
1
+ /*
2
+ * @Author : Lihao leolihao@arizona.edu
3
+ * @Date : 2023-12-02 21:36:01
4
+ * @FilePath : /visualifyjs/src/core/modules/echarts/presetHandler.js
5
+ * @Description :
6
+ * Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
7
+ */
8
+ // presetHandler.js
9
+ import minimumPreset from './common';
10
+ import mmtrbc from './presets/mmtrbc';
11
+ import esodev_chromium from './presets/esodev.chromium';
12
+ import esodev_codex from './presets/esodev.codex';
13
+ import esodev_visium from './presets/esodev.visium';
14
+
15
+ // Example embedded presets
16
+ const embeddedPresets = {
17
+ mmtrbc: mmtrbc,
18
+ esodev_chromium: esodev_chromium,
19
+ esodev_codex: esodev_codex,
20
+ esodev_visium: esodev_visium,
21
+ // 'presetName': { ...preset data... }
22
+ // Define embedded presets here
23
+ };
24
+
25
+ // Function to fetch preset data from a URL
26
+ export const fetchPresetFromURL = async (url) => {
27
+ try {
28
+ const response = await fetch(url);
29
+ const data = await response.json();
30
+ return data;
31
+ } catch (error) {
32
+ console.error('Error fetching preset from URL:', error);
33
+ return null; // Return null or appropriate error handling
34
+ }
35
+ };
36
+
37
+ // Function to get an embedded preset based on a string key
38
+ export const getEmbeddedPreset = (presetKey) => {
39
+ // Return minimumPreset if preset not found
40
+ return embeddedPresets[presetKey] || minimumPreset;
41
+ };