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
@@ -0,0 +1,271 @@
1
+ /**
2
+ * @fileoverview Docsify Markdown Processor for Visualify
3
+ * @module docsify/markdown
4
+ *
5
+ * Parses visualify code blocks in markdown and converts them
6
+ * to HTML with data attributes for chart mounting.
7
+ */
8
+
9
+ /**
10
+ * Default chart configuration
11
+ * @type {Object}
12
+ */
13
+ const DEFAULT_CONFIG = {
14
+ type: 'scatter',
15
+ };
16
+
17
+ /**
18
+ * Valid chart types
19
+ * @type {string[]}
20
+ */
21
+ const VALID_CHART_TYPES = [
22
+ 'scatter',
23
+ 'scatter3d',
24
+ 'line',
25
+ 'bar',
26
+ 'pie',
27
+ 'heatmap',
28
+ 'violin',
29
+ 'dotplot',
30
+ 'hilbert',
31
+ 'visium',
32
+ ];
33
+
34
+ /**
35
+ * Validate and normalize chart configuration
36
+ * @param {Object} config - Raw configuration object
37
+ * @returns {Object} Normalized configuration
38
+ */
39
+ function validateConfig(config) {
40
+ if (!config || typeof config !== 'object') {
41
+ console.warn('[VisualifyDocs] Invalid config, using defaults');
42
+ return { ...DEFAULT_CONFIG };
43
+ }
44
+
45
+ const normalized = { ...DEFAULT_CONFIG, ...config };
46
+
47
+ // Validate chart type
48
+ if (normalized.type && !VALID_CHART_TYPES.includes(normalized.type)) {
49
+ console.warn(
50
+ `[VisualifyDocs] Unknown chart type "${normalized.type}", defaulting to "scatter"`
51
+ );
52
+ normalized.type = 'scatter';
53
+ }
54
+
55
+ // Ensure data property exists
56
+ if (!normalized.data && !normalized.src) {
57
+ console.warn('[VisualifyDocs] No data or src provided, chart may fail to render');
58
+ }
59
+
60
+ return normalized;
61
+ }
62
+
63
+ /**
64
+ * Parse JSON safely with error handling
65
+ * @param {string} json - JSON string to parse
66
+ * @param {string} [context] - Context for error messages
67
+ * @returns {Object|null} Parsed object or null on error
68
+ */
69
+ function safeJsonParse(json, context = 'unknown') {
70
+ try {
71
+ return JSON.parse(json);
72
+ } catch (err) {
73
+ console.warn(`[VisualifyDocs] JSON parse error in ${context}:`, err.message);
74
+ return null;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Generate a unique ID for chart containers
80
+ * @returns {string} Unique ID
81
+ */
82
+ function generateChartId() {
83
+ return `visualify-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
84
+ }
85
+
86
+ /**
87
+ * Process inline visualify configuration
88
+ * @param {string} code - Code block content (JSON)
89
+ * @returns {string} HTML output
90
+ */
91
+ function processInlineConfig(code) {
92
+ const config = safeJsonParse(code, 'inline config');
93
+
94
+ if (!config) {
95
+ return renderError('Invalid JSON in visualify code block');
96
+ }
97
+
98
+ const normalizedConfig = validateConfig(config);
99
+ const chartId = generateChartId();
100
+
101
+ return renderChartContainer(chartId, normalizedConfig);
102
+ }
103
+
104
+ /**
105
+ * Process external file reference
106
+ * @param {Object} config - Configuration with src property
107
+ * @returns {string} HTML output
108
+ */
109
+ function processExternalFile(config) {
110
+ const chartId = generateChartId();
111
+ return renderChartContainer(chartId, config);
112
+ }
113
+
114
+ /**
115
+ * Render chart container HTML
116
+ * @param {string} id - Unique chart ID
117
+ * @param {Object} config - Chart configuration
118
+ * @returns {string} HTML string
119
+ */
120
+ function renderChartContainer(id, config) {
121
+ const configJson = JSON.stringify(config).replace(/"/g, '"');
122
+ const { type = 'scatter' } = config;
123
+
124
+ return (
125
+ `<div class="visualify-chart-wrapper" data-visualify-type="${type}">` +
126
+ `<div ` +
127
+ `id="${id}" ` +
128
+ `class="visualify-chart-container" ` +
129
+ `data-visualify="${configJson}" ` +
130
+ `style="width: 100%; min-height: 400px;"` +
131
+ `></div>` +
132
+ `</div>`
133
+ );
134
+ }
135
+
136
+ /**
137
+ * Render error message HTML
138
+ * @param {string} message - Error message
139
+ * @returns {string} HTML string
140
+ */
141
+ function renderError(message) {
142
+ return (
143
+ `<div class="visualify-error" style="` +
144
+ `padding: 16px; ` +
145
+ `border: 1px solid #ff4d4f; ` +
146
+ `border-radius: 4px; ` +
147
+ `background: #fff2f0; ` +
148
+ `color: #cf1322; ` +
149
+ `margin: 16px 0;` +
150
+ `">` +
151
+ `<strong>Visualify Error:</strong> ${escapeHtml(message)}` +
152
+ `</div>`
153
+ );
154
+ }
155
+
156
+ /**
157
+ * Escape HTML special characters
158
+ * @param {string} text - Text to escape
159
+ * @returns {string} Escaped text
160
+ */
161
+ function escapeHtml(text) {
162
+ const div = typeof document !== 'undefined' ? document.createElement('div') : null;
163
+ if (div) {
164
+ div.textContent = text;
165
+ return div.innerHTML;
166
+ }
167
+ // Server-side fallback
168
+ return text
169
+ .replace(/&/g, '&amp;')
170
+ .replace(/</g, '&lt;')
171
+ .replace(/>/g, '&gt;')
172
+ .replace(/"/g, '&quot;')
173
+ .replace(/'/g, '&#039;');
174
+ }
175
+
176
+ /**
177
+ * Process visualify code block content
178
+ * @param {string} code - Code block content
179
+ * @returns {string} HTML output
180
+ */
181
+ function processMarkdown(code) {
182
+ if (!code || typeof code !== 'string') {
183
+ return renderError('Empty visualify code block');
184
+ }
185
+
186
+ const trimmedCode = code.trim();
187
+
188
+ if (!trimmedCode) {
189
+ return renderError('Empty visualify code block');
190
+ }
191
+
192
+ // Try to parse as JSON
193
+ const config = safeJsonParse(trimmedCode, 'markdown processor');
194
+
195
+ if (!config) {
196
+ return renderError('Invalid JSON in visualify code block. Ensure your configuration is valid JSON.');
197
+ }
198
+
199
+ // Check for external file reference
200
+ if (config.src) {
201
+ return processExternalFile(config);
202
+ }
203
+
204
+ // Process inline configuration
205
+ return processInlineConfig(trimmedCode);
206
+ }
207
+
208
+ /**
209
+ * Process visualify code blocks in full markdown content
210
+ * Useful for pre-processing before Docsify renders
211
+ * @param {string} content - Full markdown content
212
+ * @returns {string} Processed markdown with HTML placeholders
213
+ */
214
+ function processVisualifyBlocks(content) {
215
+ if (!content || typeof content !== 'string') {
216
+ return content;
217
+ }
218
+
219
+ // Match visualify code blocks
220
+ const visualifyRegex = /```visualify\n([\s\S]*?)```/g;
221
+
222
+ return content.replace(visualifyRegex, (match, code) => {
223
+ return processMarkdown(code);
224
+ });
225
+ }
226
+
227
+ /**
228
+ * Extract visualify configurations from markdown
229
+ * Useful for search indexing or pre-loading
230
+ * @param {string} content - Markdown content
231
+ * @returns {Array<Object>} Array of chart configurations
232
+ */
233
+ function extractConfigs(content) {
234
+ if (!content || typeof content !== 'string') {
235
+ return [];
236
+ }
237
+
238
+ const configs = [];
239
+ const visualifyRegex = /```visualify\n([\s\S]*?)```/g;
240
+ let match;
241
+
242
+ while ((match = visualifyRegex.exec(content)) !== null) {
243
+ const config = safeJsonParse(match[1], 'config extraction');
244
+ if (config) {
245
+ configs.push(validateConfig(config));
246
+ }
247
+ }
248
+
249
+ return configs;
250
+ }
251
+
252
+ /**
253
+ * Check if content has visualify blocks (fast check)
254
+ * @param {string} content - Markdown content
255
+ * @returns {boolean}
256
+ */
257
+ function hasVisualifyBlocks(content) {
258
+ return typeof content === 'string' && content.includes('```visualify');
259
+ }
260
+
261
+ export {
262
+ processMarkdown,
263
+ processVisualifyBlocks,
264
+ extractConfigs,
265
+ validateConfig,
266
+ hasVisualifyBlocks,
267
+ DEFAULT_CONFIG,
268
+ VALID_CHART_TYPES,
269
+ };
270
+
271
+ export default processMarkdown;
@@ -0,0 +1,268 @@
1
+ /**
2
+ * @fileoverview Docsify Plugin Hook for Visualify
3
+ * @module docsify/plugin
4
+ *
5
+ * Hooks into Docsify's lifecycle to process visualify code blocks
6
+ * and auto-mount charts with data-visualify attribute.
7
+ */
8
+
9
+ import { processMarkdown } from './markdown';
10
+
11
+ /**
12
+ * Chart instance registry for cleanup
13
+ * @type {WeakMap<Element, Object>}
14
+ */
15
+ const chartRegistry = new WeakMap();
16
+
17
+ /**
18
+ * Lazy-loaded Visualify components
19
+ * @type {Object|null}
20
+ */
21
+ let VisualifyComponents = null;
22
+
23
+ /**
24
+ * Loading promise to prevent duplicate loads
25
+ * @type {Promise|null}
26
+ */
27
+ let loadPromise = null;
28
+
29
+ /**
30
+ * Lazy load Visualify components only when needed
31
+ * @returns {Promise<Object>} Visualify components
32
+ */
33
+ async function loadVisualifyComponents() {
34
+ if (VisualifyComponents) {
35
+ return VisualifyComponents;
36
+ }
37
+
38
+ if (loadPromise) {
39
+ return loadPromise;
40
+ }
41
+
42
+ loadPromise = import('../core/recharts')
43
+ .then((module) => {
44
+ VisualifyComponents = {
45
+ Recharts: module.default,
46
+ };
47
+ return VisualifyComponents;
48
+ })
49
+ .catch((err) => {
50
+ console.error('[VisualifyDocs] Failed to load Visualify components:', err);
51
+ throw err;
52
+ });
53
+
54
+ return loadPromise;
55
+ }
56
+
57
+ /**
58
+ * Mount a chart on a single element
59
+ * @param {Element} el - DOM element to mount chart on
60
+ * @param {Object} [config] - Optional config (parsed from data-visualify if not provided)
61
+ */
62
+ async function mountChart(el, config) {
63
+ // Skip if already mounted
64
+ if (el.dataset.visualifyMounted === 'true') {
65
+ return;
66
+ }
67
+
68
+ try {
69
+ const chartConfig = config || JSON.parse(el.dataset.visualify || '{}');
70
+
71
+ // Handle external file reference
72
+ if (chartConfig.src) {
73
+ const response = await fetch(chartConfig.src);
74
+ if (!response.ok) {
75
+ throw new Error(`Failed to fetch ${chartConfig.src}: ${response.statusText}`);
76
+ }
77
+ const externalConfig = await response.json();
78
+ Object.assign(chartConfig, externalConfig);
79
+ delete chartConfig.src;
80
+ }
81
+
82
+ // Load Visualify components lazily
83
+ const { Recharts } = await loadVisualifyComponents();
84
+
85
+ // Create and mount chart
86
+ const chart = new Recharts(chartConfig);
87
+ chart.mount(el);
88
+
89
+ // Track for cleanup
90
+ chartRegistry.set(el, chart);
91
+ el.dataset.visualifyMounted = 'true';
92
+
93
+ // Store config for potential re-mounting
94
+ el.dataset.visualify = JSON.stringify(chartConfig);
95
+ } catch (err) {
96
+ console.error('[VisualifyDocs] Failed to mount chart:', err);
97
+
98
+ // Display error in place of chart
99
+ el.innerHTML = `<div style="
100
+ padding: 16px;
101
+ border: 1px solid #ff4d4f;
102
+ border-radius: 4px;
103
+ background: #fff2f0;
104
+ color: #cf1322;
105
+ ">
106
+ <strong>Visualify Error:</strong> ${err.message}
107
+ </div>`;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Mount all charts in a container
113
+ * @param {Element} [container] - Container element (defaults to document)
114
+ */
115
+ async function mountAllCharts(container = document) {
116
+ const elements = container.querySelectorAll('[data-visualify]:not([data-visualify-mounted="true"])');
117
+
118
+ if (elements.length === 0) {
119
+ return;
120
+ }
121
+
122
+ // Load components once for all charts
123
+ await loadVisualifyComponents();
124
+
125
+ // Mount all charts
126
+ const mountPromises = Array.from(elements).map((el) => mountChart(el));
127
+ await Promise.all(mountPromises);
128
+ }
129
+
130
+ /**
131
+ * Cleanup charts in a container (for SPA navigation)
132
+ * @param {Element} [container] - Container element (defaults to document)
133
+ */
134
+ function cleanupCharts(container = document) {
135
+ const elements = container.querySelectorAll('[data-visualify]');
136
+
137
+ elements.forEach((el) => {
138
+ const chart = chartRegistry.get(el);
139
+ if (chart && typeof chart.dispose === 'function') {
140
+ chart.dispose();
141
+ }
142
+ chartRegistry.delete(el);
143
+ el.dataset.visualifyMounted = 'false';
144
+ });
145
+ }
146
+
147
+ /**
148
+ * Check if markdown contains visualify code blocks
149
+ * @param {string} content - Markdown content
150
+ * @returns {boolean}
151
+ */
152
+ function hasVisualifyBlocks(content) {
153
+ return /```visualify\n/.test(content);
154
+ }
155
+
156
+ /**
157
+ * Docsify plugin install function
158
+ * @param {Object} hook - Docsify hook object
159
+ * @param {Object} vm - Docsify vm instance
160
+ */
161
+ function install(hook, vm) {
162
+ // Initialize - called before Docsify starts
163
+ hook.init(function () {
164
+ console.log('[VisualifyDocs] Initializing Docsify plugin...');
165
+
166
+ // Add custom markdown configuration
167
+ if (window.$docsify && window.$docsify.markdown) {
168
+ const originalRenderer = window.$docsify.markdown.renderer;
169
+
170
+ window.$docsify.markdown.renderer = {
171
+ ...originalRenderer,
172
+ code: function (code, lang) {
173
+ if (lang === 'visualify') {
174
+ return processMarkdown(code);
175
+ }
176
+ // Fall back to original renderer for other languages
177
+ if (originalRenderer && originalRenderer.code) {
178
+ return originalRenderer.code.call(this, code, lang);
179
+ }
180
+ return `<pre><code class="lang-${lang}">${code}</code></pre>`;
181
+ },
182
+ };
183
+ }
184
+ });
185
+
186
+ // Before each page load - cleanup previous charts
187
+ hook.beforeEach(function (content) {
188
+ // Check if we need to load Visualify (optimization)
189
+ if (hasVisualifyBlocks(content)) {
190
+ // Preload components in background
191
+ loadVisualifyComponents().catch(() => {
192
+ // Silently fail - will retry on mount
193
+ });
194
+ }
195
+ return content;
196
+ });
197
+
198
+ // After each markdown parsing - process any remaining blocks
199
+ hook.afterEach(function (html, next) {
200
+ // If markdown renderer didn't catch all blocks (e.g., via plugin order)
201
+ // We can process them here as a fallback
202
+ next(html);
203
+ });
204
+
205
+ // Mounted - initial page load
206
+ hook.mounted(function () {
207
+ console.log('[VisualifyDocs] Docsify mounted, scanning for charts...');
208
+ mountAllCharts();
209
+ });
210
+
211
+ // Done each - after each route change (SPA navigation)
212
+ hook.doneEach(function () {
213
+ console.log('[VisualifyDocs] Route changed, mounting charts...');
214
+ mountAllCharts();
215
+ });
216
+
217
+ // Destroyed - cleanup when leaving
218
+ hook.destroyed(function () {
219
+ console.log('[VisualifyDocs] Cleaning up charts...');
220
+ cleanupCharts();
221
+ });
222
+ }
223
+
224
+ /**
225
+ * Global API for manual chart mounting
226
+ */
227
+ const VisualifyDocsify = {
228
+ install,
229
+ mountChart,
230
+ mountAllCharts,
231
+ cleanupCharts,
232
+ loadVisualifyComponents,
233
+
234
+ /**
235
+ * Check if an element has a mounted chart
236
+ * @param {Element} el - DOM element
237
+ * @returns {boolean}
238
+ */
239
+ isMounted(el) {
240
+ return el.dataset.visualifyMounted === 'true';
241
+ },
242
+
243
+ /**
244
+ * Get chart instance for an element
245
+ * @param {Element} el - DOM element
246
+ * @returns {Object|null}
247
+ */
248
+ getChart(el) {
249
+ return chartRegistry.get(el) || null;
250
+ },
251
+
252
+ /**
253
+ * Version info
254
+ */
255
+ version: process.env.VISUALIFY_VERSION || 'dev',
256
+ };
257
+
258
+ // Auto-install if Docsify is present
259
+ if (typeof window !== 'undefined' && window.$docsify) {
260
+ window.$docsify.plugins = [].concat(
261
+ window.$docsify.plugins || [],
262
+ install
263
+ );
264
+ console.log('[VisualifyDocs] Auto-registered with Docsify');
265
+ }
266
+
267
+ export default VisualifyDocsify;
268
+ export { install, mountChart, mountAllCharts, cleanupCharts, loadVisualifyComponents };
@@ -0,0 +1,172 @@
1
+ # Visualify Visual Editor
2
+
3
+ A visual configuration editor for Visualify.js that makes it easy to create and edit chart configurations without writing JSON.
4
+
5
+ ## Features
6
+
7
+ - **Drag-and-Drop Interface**: Build charts by dragging chart types from the sidebar
8
+ - **Property Panels**: Dynamic forms for each chart type (2D and 3D)
9
+ - **Live Preview**: Real-time chart rendering as you edit
10
+ - **Import/Export**: Load and save `visualify.json` configurations
11
+ - **Undo/Redo History**: Full editing history with keyboard shortcuts
12
+ - **Auto-Save**: Automatic saving to localStorage
13
+ - **Responsive Design**: Works on different screen sizes
14
+
15
+ ## Supported Chart Types
16
+
17
+ ### 2D Charts
18
+ - Scatter
19
+ - Bar
20
+ - Line
21
+ - Pie
22
+ - Radar
23
+ - Funnel
24
+ - Heatmap
25
+ - Box Plot
26
+
27
+ ### 3D Charts
28
+ - 3D Scatter
29
+ - 3D Bar
30
+ - 3D Surface
31
+ - 3D Line
32
+
33
+ ## Usage
34
+
35
+ ### CLI Command
36
+
37
+ ```bash
38
+ # Open editor with default config
39
+ visualify edit
40
+
41
+ # Open specific config file
42
+ visualify edit my-config.json
43
+
44
+ # Custom port
45
+ visualify edit --port 4000
46
+
47
+ # Don't open browser automatically
48
+ visualify edit --no-open
49
+ ```
50
+
51
+ ### Programmatic Usage
52
+
53
+ ```javascript
54
+ import { mountEditor } from './editor';
55
+
56
+ // Mount editor to a DOM element
57
+ mountEditor('#editor-container', {
58
+ config: {
59
+ version: '3.0.0',
60
+ charts: [],
61
+ layout: { type: 'grid', rows: 1, cols: 1 },
62
+ theme: 'modern'
63
+ }
64
+ });
65
+ ```
66
+
67
+ ## UI Layout
68
+
69
+ ```
70
+ +------------------------------------------+
71
+ | Toolbar (New, Open, Save, Export, Undo) |
72
+ +----------+----------------+--------------+
73
+ | | | |
74
+ | Chart | Canvas | Properties |
75
+ | Types | (D&D) | Panel |
76
+ | | | |
77
+ +----------+----------------+--------------+
78
+ | Status Bar (Errors, Auto-save status) |
79
+ +------------------------------------------+
80
+ ```
81
+
82
+ ## Keyboard Shortcuts
83
+
84
+ | Shortcut | Action |
85
+ |----------|--------|
86
+ | `Ctrl/Cmd + Z` | Undo |
87
+ | `Ctrl/Cmd + Y` | Redo |
88
+ | `Ctrl/Cmd + Shift + Z` | Redo (alternative) |
89
+ | `Ctrl/Cmd + S` | Export configuration |
90
+ | `Escape` | Close modals |
91
+
92
+ ## File Structure
93
+
94
+ ```
95
+ editor/
96
+ ├── index.js # Main entry point
97
+ ├── context/
98
+ │ └── EditorContext.js # React context for state management
99
+ ├── components/
100
+ │ ├── Editor.jsx # Main editor UI
101
+ │ ├── ChartBuilder.jsx # Drag-and-drop canvas
102
+ │ ├── ChartTypeSidebar.jsx # Chart type selector
103
+ │ ├── PropertyPanel.jsx # Property editor
104
+ │ ├── Preview.jsx # Live preview
105
+ │ └── StatusBar.jsx # Status bar
106
+ ├── utils/
107
+ │ └── chartValidator.js # Configuration validation
108
+ ├── styles/
109
+ │ └── editor.css # Editor styles
110
+ └── README.md # This file
111
+ ```
112
+
113
+ ## Architecture
114
+
115
+ ### State Management
116
+
117
+ The editor uses React Context for state management with the following structure:
118
+
119
+ ```javascript
120
+ {
121
+ config: {
122
+ version: '3.0.0',
123
+ charts: [...],
124
+ layout: {...},
125
+ theme: 'modern'
126
+ },
127
+ selectedChartId: string | null,
128
+ history: {
129
+ past: [...],
130
+ present: {...},
131
+ future: [...]
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Actions
137
+
138
+ - `setConfig(config)` - Replace entire configuration
139
+ - `addChart(chart)` - Add a new chart
140
+ - `updateChart(id, updates)` - Update chart properties
141
+ - `removeChart(id)` - Remove a chart
142
+ - `setSelectedChart(id)` - Select a chart for editing
143
+ - `undo()` / `redo()` - History navigation
144
+
145
+ ## Validation
146
+
147
+ Charts are validated in real-time with checks for:
148
+
149
+ - Required fields (type, data)
150
+ - Data format compatibility
151
+ - 3D WebGL support
152
+ - Configuration completeness
153
+
154
+ ## Building
155
+
156
+ The editor is built as a React application and bundled for distribution:
157
+
158
+ ```bash
159
+ # Development
160
+ npm run editor:dev
161
+
162
+ # Build
163
+ npm run editor:build
164
+ ```
165
+
166
+ ## Browser Support
167
+
168
+ - Chrome/Edge 80+
169
+ - Firefox 75+
170
+ - Safari 13+
171
+
172
+ 3D charts require WebGL support.