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.
- package/.claude/mem/TIMELINE.md +36 -0
- package/.claude/mem/notes/2026-02-11-3d-visualization-docs-fix-external-script-solution.md +24 -0
- package/.claude/mem/notes/2026-02-11-3d-visualization-docs-fix-session-summary.md +43 -0
- package/.claude/mem/notes/2026-02-11-cli-fix-editor-command-alias.md +26 -0
- package/.claude/mem/notes/2026-02-11-phase-3-developer-experience-completed.md +51 -0
- package/.claude/mem/notes/2026-02-11-phase-4-web-workers-implementation-complete.md +59 -0
- package/.claude/mem/notes/2026-02-11-visualify-phase-2-3d-visualization-complete.md +50 -0
- package/.claude/mem/notes/2026-02-11-visualify-phase-2-committed-ready-for-phase-3.md +33 -0
- package/.claude/mem/notes/2026-02-11-visualify-phase-3-complete-developer-experience.md +52 -0
- package/.claude/mem/notes/2026-02-11-visualify-repository-cleanup-complete.md +28 -0
- package/.claude/mem/notes/2026-02-18-codebase-cleanup-docsify-plugin-documentation.md +37 -0
- package/.claude/mem/notes/2026-02-19-css-grid-layout-fix-displaycontents-on-vcontroller.md +18 -0
- package/.claude/mem/notes/2026-02-19-docsify-plugin-fixes-latex-and-visualify-code-bloc.md +26 -0
- package/.claude/mem/notes/2026-02-19-page-mode-docs-update-decisions.md +23 -0
- package/.claude/mem/notes/2026-02-19-react-context-infinite-re-render-loop-fix-pattern.md +31 -0
- package/.claude/mem/notes/2026-02-19-version-300-bump-and-build-fixes.md +32 -0
- package/.claude/mem/notes/2026-02-19-visualify-build-deployment-architecture-bug-fixes.md +25 -0
- package/.claude/mem/notes/2026-02-19-visualify-dist-iife-self-contained-build-config.md +30 -0
- package/.claude/mem/notes/2026-02-19-visualify-infinite-loop-i18n-fixes.md +31 -0
- package/.claude/mem/notes/2026-02-19-visualify-v3-bundle-splitting-docs-restructuring.md +32 -0
- package/.claude/mem/notes/2026-02-20-bundle-externalization-final-architecture.md +29 -0
- package/.claude/mem/notes/2026-02-20-chromium-page-fix-unstable-keys-and-double-event-b.md +27 -0
- package/.claude/mem/notes/2026-02-20-console-cleanup-bundle-optimization-commit.md +20 -0
- package/.claude/mem/notes/2026-02-20-dotbio-dot-plot-fix-useeffect-dependency.md +21 -0
- package/.claude/mem/notes/2026-02-20-public-folder-cleanup-and-readme-rewrite.md +25 -0
- package/.claude/mem/notes/2026-02-20-v300-release-and-beta-channel-strategy.md +29 -0
- package/.claude/mem/notes/2026-02-20-visium-background-image-unknown-legend-fix.md +19 -0
- package/.claude/mem/notes/2026-02-20-visualify-cdn-loader-bundle-externalization.md +34 -0
- package/.claude/mem/sessions/session-2026-02-20-031524.md +54 -0
- package/.claude/settings.local.json +21 -0
- package/.github/workflows/static.yml.bak +51 -51
- package/.sisyphus/boulder.json +65 -0
- package/.sisyphus/plans/phase-4-advanced-optimizations.md +217 -0
- package/LICENSE +674 -674
- package/README.md +94 -59
- package/config-overrides.js +31 -31
- package/dist/stats.html +4949 -0
- package/dist/visualify-3d.esm.js +1 -0
- package/dist/visualify-3d.js +1 -0
- package/dist/visualify-core.esm.js +1 -0
- package/dist/visualify-core.js +1 -0
- package/dist/visualify-docs.esm.js +1 -0
- package/dist/visualify-docs.js +1 -0
- package/dist/visualify-loader.js +1 -0
- package/dist/visualify-pages.esm.js +1 -0
- package/dist/visualify-pages.js +1 -0
- package/dist/visualify-portal.esm.js +1 -0
- package/dist/visualify-portal.js +1 -0
- package/dist/visualify-shared.js +26571 -0
- package/dist/visualify.js +1 -188
- package/docs/CHANGELOG.md +148 -0
- package/docs/cli/commands.md +513 -0
- package/docs/configuration/visualify-json.md +474 -0
- package/docs/docs/3d-visualization.md +374 -0
- package/docs/docs/CLI.md +303 -34
- package/docs/docs/README.md +65 -65
- package/docs/docs/Rechart/bar.md +190 -190
- package/docs/docs/Rechart/funnel.md +241 -241
- package/docs/docs/Rechart/line.md +355 -355
- package/docs/docs/Rechart/pie.md +225 -225
- package/docs/docs/Rechart/radar.md +253 -253
- package/docs/docs/Rechart/scatter.md +298 -298
- package/docs/docs/_404.md +51 -51
- package/docs/docs/_coverpage.md +11 -11
- package/docs/docs/_sidebar.md +54 -44
- package/docs/docs/components/dotBio.md +87 -34
- package/docs/docs/components/echart.md +171 -82
- package/docs/docs/components/html.md +61 -34
- package/docs/docs/components/macaron.md +156 -145
- package/docs/docs/components/markdown.md +42 -0
- package/docs/docs/components/more.md +183 -142
- package/docs/docs/components/plotly.md +132 -62
- package/docs/docs/components/scatterL.md +171 -70
- package/docs/docs/components/visium.md +112 -57
- package/docs/docs/configuration.md +121 -121
- package/docs/docs/deploy.md +31 -31
- package/docs/docs/docsify-plugin.md +655 -0
- package/docs/docs/hmr.md +165 -0
- package/docs/docs/i18n.md +332 -0
- package/docs/docs/log.md +30 -9
- package/docs/docs/more-pages.md +23 -23
- package/docs/docs/quickstart.md +148 -124
- package/docs/docs/rechart-attributes.md +74 -74
- package/docs/docs/rechart-basic-usage.md +160 -162
- package/docs/docs/theme.md +5 -5
- package/docs/docs/typescript.md +306 -0
- package/docs/docs/visual-editor.md +359 -0
- package/docs/index.html +85 -71
- package/docs/manifest.json +23 -23
- package/docs/migration/v3-migration.md +392 -0
- package/docs/static/css/fluff-stuff.css +169 -169
- package/docs/static/css/font-awesome.min.css +4 -4
- package/docs/static/css/visualify.css +6 -25
- package/docs/static/js/3d-viz-examples.js +181 -0
- package/docs/static/js/configuration.js +630 -448
- package/docs/static/js/visualify.js +1 -188
- package/package.json +106 -84
- package/rollup.config.mjs +766 -76
- package/src/_css/404.css +115 -115
- package/src/_css/App.css +37 -37
- package/src/_css/autoSuggestion.css +26 -26
- package/src/_css/circular-progress.css +32 -32
- package/src/_css/index.css +36 -36
- package/src/_css/modern.css +350 -25
- package/src/_media/corner.svg +8 -8
- package/src/_media/download.svg +3 -3
- package/src/_media/logo.svg +14 -14
- package/src/_test/App.test.js +15 -15
- package/src/_utils/reportWebVitals.js +13 -13
- package/src/a11y/README.md +177 -0
- package/src/a11y/aria-labels.js +339 -0
- package/src/a11y/color-contrast.js +535 -0
- package/src/a11y/index.js +197 -0
- package/src/a11y/keyboard-nav.js +523 -0
- package/src/a11y/styles.css +165 -0
- package/src/cli/commands/dev.js +214 -0
- package/src/cli/commands/docs.js +521 -0
- package/src/cli/commands/edit.js +379 -0
- package/src/cli/commands/init.js +213 -0
- package/src/cli/commands/portal.js +236 -0
- package/src/cli/dev-server.js +530 -0
- package/src/cli/hmr.js +456 -0
- package/src/cli/index.js +180 -0
- package/src/cli/utils/config.js +207 -0
- package/src/cli/utils/logger.js +241 -0
- package/src/config/defaults.ts +122 -0
- package/src/config/index.ts +72 -0
- package/src/config/loader.ts +478 -0
- package/src/config/schema.ts +227 -0
- package/src/config/validator.ts +337 -0
- package/src/core/appContext.js +34 -27
- package/src/core/components/Bar.js +383 -0
- package/src/core/components/Bar3D.js +473 -0
- package/src/core/components/LargeDatasetChart.js +296 -0
- package/src/core/components/Line3D.js +310 -0
- package/src/core/components/Scatter.js +392 -188
- package/src/core/components/Scatter3D.js +455 -0
- package/src/core/components/ScatterBio.js +601 -572
- package/src/core/components/Surface3D.js +326 -0
- package/src/core/components/ThreeCustom.js +648 -0
- package/src/core/components/ThreeScene.js +459 -0
- package/src/core/components/VisiumPlot.js +191 -165
- package/src/core/components/browser.js +42 -42
- package/src/core/components/dotplot.js +413 -413
- package/src/core/components/html.js +29 -29
- package/src/core/components/list.js +178 -178
- package/src/core/components/macaron.js +206 -201
- package/src/core/components/markdown.js +56 -56
- package/src/core/components/parser.scatterBio.js +582 -587
- package/src/core/components/ratio.js +82 -80
- package/src/core/components/scatterL.js +206 -173
- package/src/core/components/searchbar.js +156 -131
- package/src/core/components/selection.js +310 -193
- package/src/core/components/timeline.js +236 -281
- package/src/core/components/visium.js +114 -97
- package/src/core/data-processor.js +413 -0
- package/src/core/fetch/condfetch.js +82 -82
- package/src/core/fetch/fetch.js +92 -92
- package/src/core/fetch/json.js +29 -29
- package/src/core/fetch/vfetch.js +42 -42
- package/src/core/hmr-client.js +724 -0
- package/src/core/liveEditor.js +44 -44
- package/src/core/modules/codeEditorWithPreview.js +104 -104
- package/src/core/modules/echarts/common.js +20 -20
- package/src/core/modules/echarts/gl.js +228 -0
- package/src/core/modules/echarts/presetHandler.js +41 -41
- package/src/core/modules/echarts/presets/esodev.chromium.js +172 -172
- package/src/core/modules/echarts/presets/esodev.codex.js +130 -130
- package/src/core/modules/echarts/presets/esodev.visium.js +123 -123
- package/src/core/modules/echarts/presets/mmtrbc.js +186 -186
- package/src/core/modules/echarts.js +70 -71
- package/src/core/modules/echartsUtils.js +43 -43
- package/src/core/modules/echartswitcher.js +227 -152
- package/src/core/modules/replotly/presetHandler.js +24 -24
- package/src/core/modules/replotly/presets/minimum.js +18 -18
- package/src/core/modules/replotly/presets/mmtrbc.dot.js +114 -114
- package/src/core/modules/replotly/presets/mmtrbc.violin.js +100 -100
- package/src/core/modules/replotly.js +74 -71
- package/src/core/modules/threejs/Camera.js +373 -0
- package/src/core/modules/threejs/Lighting.js +459 -0
- package/src/core/modules/threejs/Renderer.js +364 -0
- package/src/core/modules/threejs/Scene.js +266 -0
- package/src/core/modules/threejs/index.js +155 -0
- package/src/core/pages/404.js +50 -50
- package/src/core/pages/error.js +27 -27
- package/src/core/pages/jsonPage.js +62 -62
- package/src/core/pages/loading.js +44 -44
- package/src/core/parser/echart.data.js +204 -183
- package/src/core/parser/echart.features.js +125 -125
- package/src/core/parser/echart.general.js +147 -147
- package/src/core/parser/echart.hilbert.js +57 -57
- package/src/core/parser/echart.parser.js +210 -210
- package/src/core/parser/echart.series.js +67 -67
- package/src/core/parser/echart.types.js +76 -76
- package/src/core/parser/plotly.config.js +10 -10
- package/src/core/parser/plotly.data.js +132 -132
- package/src/core/parser/plotly.layout.js +9 -9
- package/src/core/parser/plotly.violin.js +18 -18
- package/src/core/recharts.js +361 -62
- package/src/core/router/alias.js +49 -49
- package/src/core/router/jsonRouter.js +31 -31
- package/src/core/themes/modern.js +32 -32
- package/src/core/themes/themeSelector.js +33 -33
- package/src/core/visualify.js +213 -47
- package/src/core/widgets/circularProgress.js +23 -23
- package/src/core/widgets/controller.js +116 -83
- package/src/core/widgets/errorBoundary.js +36 -36
- package/src/core/widgets/footer.js +185 -177
- package/src/core/widgets/header.js +238 -234
- package/src/core/widgets/layout/Grid.js +31 -31
- package/src/core/widgets/layout.js +36 -36
- package/src/core/widgets/mapping.js +56 -42
- package/src/core/workers/data-worker.js +349 -0
- package/src/core/workers/worker-pool.js +396 -0
- package/src/docsify/bundle.js +215 -0
- package/src/docsify/markdown.js +271 -0
- package/src/docsify/plugin.js +268 -0
- package/src/editor/README.md +172 -0
- package/src/editor/components/ChartBuilder.jsx +341 -0
- package/src/editor/components/ChartTypeSidebar.jsx +91 -0
- package/src/editor/components/Editor.jsx +367 -0
- package/src/editor/components/Preview.jsx +446 -0
- package/src/editor/components/PropertyPanel.jsx +468 -0
- package/src/editor/components/StatusBar.jsx +85 -0
- package/src/editor/context/EditorContext.js +248 -0
- package/src/editor/hooks/useDebounce.js +32 -0
- package/src/editor/index.js +315 -0
- package/src/editor/styles/editor.css +637 -0
- package/src/editor/utils/chartValidator.js +263 -0
- package/src/entries/charts3d.js +70 -0
- package/src/entries/core.js +78 -0
- package/src/entries/docs.js +154 -0
- package/src/entries/pages.js +93 -0
- package/src/entries/portal.js +204 -0
- package/src/entries/shared.js +50 -0
- package/src/i18n/formatters.js +455 -0
- package/src/i18n/index.js +169 -0
- package/src/i18n/locales/ar.json +137 -0
- package/src/i18n/locales/de.json +137 -0
- package/src/i18n/locales/en.json +137 -0
- package/src/i18n/locales/es.json +137 -0
- package/src/i18n/locales/he.json +137 -0
- package/src/i18n/locales/zh.json +137 -0
- package/src/i18n/rtl.css +183 -0
- package/src/index.js +82 -62
- package/src/loader.js +103 -0
- package/src/setupTests.js +5 -5
- package/tsconfig.json +51 -0
- package/types/charts.d.ts +569 -0
- package/types/components.d.ts +441 -0
- package/types/config.d.ts +199 -0
- package/types/index.d.ts +353 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Chart Configuration Validator
|
|
3
|
+
* @module editor/utils/chartValidator
|
|
4
|
+
*
|
|
5
|
+
* Validates chart configurations for different chart types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validation error
|
|
10
|
+
*/
|
|
11
|
+
class ValidationError extends Error {
|
|
12
|
+
constructor(message, field = null) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'ValidationError';
|
|
15
|
+
this.field = field;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Chart type definitions and their required fields
|
|
21
|
+
*/
|
|
22
|
+
const CHART_SCHEMAS = {
|
|
23
|
+
scatter: {
|
|
24
|
+
required: ['data'],
|
|
25
|
+
dataFormat: [
|
|
26
|
+
{ x: 'number', y: 'number' },
|
|
27
|
+
{ value: 'array' },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
scatter3d: {
|
|
31
|
+
required: ['data'],
|
|
32
|
+
dataFormat: [{ x: 'number', y: 'number', z: 'number' }],
|
|
33
|
+
},
|
|
34
|
+
bar: {
|
|
35
|
+
required: ['data'],
|
|
36
|
+
dataFormat: [{ category: 'string', value: 'number' }],
|
|
37
|
+
},
|
|
38
|
+
bar3d: {
|
|
39
|
+
required: ['data'],
|
|
40
|
+
dataFormat: [{ category: 'string', value: 'number' }],
|
|
41
|
+
},
|
|
42
|
+
line: {
|
|
43
|
+
required: ['data'],
|
|
44
|
+
dataFormat: [{ x: 'any', y: 'number' }],
|
|
45
|
+
},
|
|
46
|
+
line3d: {
|
|
47
|
+
required: ['data'],
|
|
48
|
+
dataFormat: [{ x: 'number', y: 'number', z: 'number' }],
|
|
49
|
+
},
|
|
50
|
+
pie: {
|
|
51
|
+
required: ['data'],
|
|
52
|
+
dataFormat: [{ name: 'string', value: 'number' }],
|
|
53
|
+
},
|
|
54
|
+
radar: {
|
|
55
|
+
required: ['data', 'options.radar.indicator'],
|
|
56
|
+
dataFormat: [{ name: 'string', value: 'array' }],
|
|
57
|
+
},
|
|
58
|
+
funnel: {
|
|
59
|
+
required: ['data'],
|
|
60
|
+
dataFormat: [{ name: 'string', value: 'number' }],
|
|
61
|
+
},
|
|
62
|
+
heatmap: {
|
|
63
|
+
required: ['data'],
|
|
64
|
+
dataFormat: ['array'],
|
|
65
|
+
},
|
|
66
|
+
boxplot: {
|
|
67
|
+
required: ['data'],
|
|
68
|
+
dataFormat: ['array'],
|
|
69
|
+
},
|
|
70
|
+
surface3d: {
|
|
71
|
+
required: [],
|
|
72
|
+
dataFormat: [],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate data point against format
|
|
78
|
+
* @param {Object} dataPoint - Data point to validate
|
|
79
|
+
* @param {Object} format - Expected format
|
|
80
|
+
* @returns {boolean}
|
|
81
|
+
*/
|
|
82
|
+
function validateDataPoint(dataPoint, format) {
|
|
83
|
+
if (typeof format === 'string') {
|
|
84
|
+
if (format === 'array') {
|
|
85
|
+
return Array.isArray(dataPoint);
|
|
86
|
+
}
|
|
87
|
+
return typeof dataPoint === format;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (typeof format === 'object' && format !== null) {
|
|
91
|
+
return Object.entries(format).every(([key, type]) => {
|
|
92
|
+
if (!(key in dataPoint)) return false;
|
|
93
|
+
|
|
94
|
+
const value = dataPoint[key];
|
|
95
|
+
if (type === 'any') return true;
|
|
96
|
+
if (type === 'array') return Array.isArray(value);
|
|
97
|
+
if (type === 'number')
|
|
98
|
+
return typeof value === 'number' || !isNaN(parseFloat(value));
|
|
99
|
+
return typeof value === type;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get nested value from object
|
|
108
|
+
* @param {Object} obj - Object to traverse
|
|
109
|
+
* @param {string} path - Dot-separated path
|
|
110
|
+
* @returns {any}
|
|
111
|
+
*/
|
|
112
|
+
function getNestedValue(obj, path) {
|
|
113
|
+
return path.split('.').reduce((current, key) => {
|
|
114
|
+
return current?.[key];
|
|
115
|
+
}, obj);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Validate chart configuration
|
|
120
|
+
* @param {Object} chart - Chart configuration
|
|
121
|
+
* @returns {Object} Validation result
|
|
122
|
+
*/
|
|
123
|
+
export function validateChart(chart) {
|
|
124
|
+
const errors = [];
|
|
125
|
+
const warnings = [];
|
|
126
|
+
|
|
127
|
+
// Check required fields
|
|
128
|
+
if (!chart.type) {
|
|
129
|
+
errors.push(new ValidationError('Chart type is required', 'type'));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!chart.title) {
|
|
133
|
+
warnings.push(new ValidationError('Chart title is recommended', 'title'));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const schema = CHART_SCHEMAS[chart.type];
|
|
137
|
+
if (!schema) {
|
|
138
|
+
errors.push(new ValidationError(`Unknown chart type: ${chart.type}`, 'type'));
|
|
139
|
+
return { valid: false, errors, warnings };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Check schema requirements
|
|
143
|
+
for (const field of schema.required) {
|
|
144
|
+
const value = getNestedValue(chart, field);
|
|
145
|
+
if (value === undefined || value === null) {
|
|
146
|
+
errors.push(new ValidationError(`Missing required field: ${field}`, field));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Validate data format
|
|
151
|
+
if (chart.data && Array.isArray(chart.data)) {
|
|
152
|
+
if (chart.data.length === 0) {
|
|
153
|
+
warnings.push(new ValidationError('Chart has no data points', 'data'));
|
|
154
|
+
} else {
|
|
155
|
+
// Check first data point against expected formats
|
|
156
|
+
const firstPoint = chart.data[0];
|
|
157
|
+
const validFormat = schema.dataFormat.some((format) =>
|
|
158
|
+
validateDataPoint(firstPoint, format),
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
if (!validFormat && schema.dataFormat.length > 0) {
|
|
162
|
+
const expectedFormat = schema.dataFormat
|
|
163
|
+
.map((f) =>
|
|
164
|
+
typeof f === 'string'
|
|
165
|
+
? f
|
|
166
|
+
: JSON.stringify(f),
|
|
167
|
+
)
|
|
168
|
+
.join(' or ');
|
|
169
|
+
warnings.push(
|
|
170
|
+
new ValidationError(
|
|
171
|
+
`Data format may be incorrect. Expected: ${expectedFormat}`,
|
|
172
|
+
'data',
|
|
173
|
+
),
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
} else if (schema.required.includes('data')) {
|
|
178
|
+
errors.push(new ValidationError('Chart data must be an array', 'data'));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Validate 3D specific requirements
|
|
182
|
+
if (chart.type.includes('3d')) {
|
|
183
|
+
// Note: In a real implementation, we would check for WebGL support here
|
|
184
|
+
warnings.push(
|
|
185
|
+
new ValidationError(
|
|
186
|
+
'3D charts require WebGL support in the browser',
|
|
187
|
+
'type',
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
valid: errors.length === 0,
|
|
194
|
+
errors,
|
|
195
|
+
warnings,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Validate complete configuration
|
|
201
|
+
* @param {Object} config - Full configuration
|
|
202
|
+
* @returns {Object} Validation result
|
|
203
|
+
*/
|
|
204
|
+
export function validateConfig(config) {
|
|
205
|
+
const errors = [];
|
|
206
|
+
const warnings = [];
|
|
207
|
+
|
|
208
|
+
if (!config) {
|
|
209
|
+
errors.push(new ValidationError('Configuration is required'));
|
|
210
|
+
return { valid: false, errors, warnings };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!config.charts || !Array.isArray(config.charts)) {
|
|
214
|
+
errors.push(new ValidationError('Configuration must have a charts array'));
|
|
215
|
+
} else {
|
|
216
|
+
// Validate each chart
|
|
217
|
+
config.charts.forEach((chart, index) => {
|
|
218
|
+
const result = validateChart(chart);
|
|
219
|
+
result.errors.forEach((error) => {
|
|
220
|
+
error.field = `charts[${index}].${error.field}`;
|
|
221
|
+
errors.push(error);
|
|
222
|
+
});
|
|
223
|
+
result.warnings.forEach((warning) => {
|
|
224
|
+
warning.field = `charts[${index}].${warning.field}`;
|
|
225
|
+
warnings.push(warning);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Validate layout
|
|
231
|
+
if (config.layout) {
|
|
232
|
+
const { rows, cols } = config.layout;
|
|
233
|
+
if (rows && (typeof rows !== 'number' || rows < 1)) {
|
|
234
|
+
errors.push(new ValidationError('Layout rows must be a positive number'));
|
|
235
|
+
}
|
|
236
|
+
if (cols && (typeof cols !== 'number' || cols < 1)) {
|
|
237
|
+
errors.push(new ValidationError('Layout cols must be a positive number'));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
valid: errors.length === 0,
|
|
243
|
+
errors,
|
|
244
|
+
warnings,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Format validation errors for display
|
|
250
|
+
* @param {Array} errors - Array of ValidationError
|
|
251
|
+
* @returns {string}
|
|
252
|
+
*/
|
|
253
|
+
export function formatValidationErrors(errors) {
|
|
254
|
+
return errors
|
|
255
|
+
.map((error) => {
|
|
256
|
+
const field = error.field ? `[${error.field}] ` : '';
|
|
257
|
+
return `${field}${error.message}`;
|
|
258
|
+
})
|
|
259
|
+
.join('\n');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export { ValidationError, CHART_SCHEMAS };
|
|
263
|
+
export default validateChart;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 3D Charts Entry Point
|
|
3
|
+
* @description Separate chunk for 3D visualization components
|
|
4
|
+
* Loaded on demand when 3D chart types are detected
|
|
5
|
+
* Global name: Visualify3D
|
|
6
|
+
*
|
|
7
|
+
* External dependencies (not bundled):
|
|
8
|
+
* - three
|
|
9
|
+
* - @react-three/fiber
|
|
10
|
+
* - @react-three/drei
|
|
11
|
+
* - echarts-gl
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// 3D visualization components
|
|
15
|
+
export { default as Scatter3D } from '../core/components/Scatter3D';
|
|
16
|
+
export { default as Bar3D } from '../core/components/Bar3D';
|
|
17
|
+
export { default as Surface3D } from '../core/components/Surface3D';
|
|
18
|
+
export { default as Line3D } from '../core/components/Line3D';
|
|
19
|
+
export { default as ThreeScene } from '../core/components/ThreeScene';
|
|
20
|
+
export { default as ThreeCustom } from '../core/components/ThreeCustom';
|
|
21
|
+
|
|
22
|
+
// ECharts GL integration (lazy loading, WebGL detection)
|
|
23
|
+
export {
|
|
24
|
+
isWebGLSupported,
|
|
25
|
+
getWebGLInfo,
|
|
26
|
+
loadEChartsGL,
|
|
27
|
+
preloadEChartsGL,
|
|
28
|
+
getLoadingState,
|
|
29
|
+
display3DError,
|
|
30
|
+
cleanupWebGL,
|
|
31
|
+
handleWebGLContextLoss,
|
|
32
|
+
} from '../core/modules/echarts/gl';
|
|
33
|
+
|
|
34
|
+
// Three.js module
|
|
35
|
+
export { default as ThreeJS } from '../core/modules/threejs/index';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Visualify3D namespace
|
|
39
|
+
* 3D chart components loaded on demand
|
|
40
|
+
*/
|
|
41
|
+
const Visualify3D = {
|
|
42
|
+
version: process.env.VISUALIFY_VERSION || 'dev',
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Check if the current environment supports 3D rendering
|
|
46
|
+
* @returns {boolean}
|
|
47
|
+
*/
|
|
48
|
+
isSupported() {
|
|
49
|
+
try {
|
|
50
|
+
const canvas = document.createElement('canvas');
|
|
51
|
+
const gl =
|
|
52
|
+
canvas.getContext('webgl2') ||
|
|
53
|
+
canvas.getContext('webgl') ||
|
|
54
|
+
canvas.getContext('experimental-webgl');
|
|
55
|
+
return !!gl;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Preload 3D dependencies in the background
|
|
63
|
+
*/
|
|
64
|
+
async preload() {
|
|
65
|
+
const { preloadEChartsGL } = await import('../core/modules/echarts/gl');
|
|
66
|
+
preloadEChartsGL();
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default Visualify3D;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core 2D Charting Entry Point
|
|
3
|
+
* @description Lightweight bundle with core charting capabilities
|
|
4
|
+
* Includes ECharts, Recharts, parsers, themes, and essential widgets
|
|
5
|
+
* Global name: VisualifyCore
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import '../_css/index.css';
|
|
9
|
+
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
10
|
+
|
|
11
|
+
import Recharts from '../core/recharts';
|
|
12
|
+
import LiveEditor from '../core/liveEditor';
|
|
13
|
+
import { VisualifyProvider, useAppContext } from '../core/appContext';
|
|
14
|
+
|
|
15
|
+
// Core chart components
|
|
16
|
+
export { default as ReCharts } from '../core/modules/echarts';
|
|
17
|
+
export { default as EChartSwitcher } from '../core/modules/echartswitcher';
|
|
18
|
+
|
|
19
|
+
// Chart utilities and parsers
|
|
20
|
+
export * from '../core/parser/echart.data';
|
|
21
|
+
export * from '../core/parser/echart.features';
|
|
22
|
+
export * from '../core/parser/echart.series';
|
|
23
|
+
export * from '../core/parser/echart.types';
|
|
24
|
+
export * from '../core/parser/echart.parser';
|
|
25
|
+
export * from '../core/parser/echart.hilbert';
|
|
26
|
+
|
|
27
|
+
// ECharts utilities and presets
|
|
28
|
+
export * from '../core/modules/echartsUtils';
|
|
29
|
+
export { fetchPresetFromURL, getEmbeddedPreset } from '../core/modules/echarts/presetHandler';
|
|
30
|
+
export * from '../core/modules/echarts/common';
|
|
31
|
+
|
|
32
|
+
// Theme system
|
|
33
|
+
export { default as ThemeSelector } from '../core/themes/themeSelector';
|
|
34
|
+
export * from '../core/themes/modern';
|
|
35
|
+
|
|
36
|
+
// Shared widgets
|
|
37
|
+
export { default as ErrorBoundary } from '../core/widgets/errorBoundary';
|
|
38
|
+
export { default as CircularProgress } from '../core/widgets/circularProgress';
|
|
39
|
+
|
|
40
|
+
// Re-export core classes
|
|
41
|
+
export { Recharts, LiveEditor, VisualifyProvider, useAppContext };
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* VisualifyCore namespace
|
|
45
|
+
* Contains core 2D charting exports
|
|
46
|
+
*/
|
|
47
|
+
const VisualifyCore = {
|
|
48
|
+
// Version info (replaced during build)
|
|
49
|
+
version: process.env.VISUALIFY_VERSION || 'dev',
|
|
50
|
+
|
|
51
|
+
// Core classes
|
|
52
|
+
Recharts,
|
|
53
|
+
LiveEditor,
|
|
54
|
+
|
|
55
|
+
// React context
|
|
56
|
+
VisualifyProvider,
|
|
57
|
+
useAppContext,
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create a chart instance
|
|
61
|
+
* @param {Object} config - Chart configuration
|
|
62
|
+
* @returns {Recharts} Recharts instance
|
|
63
|
+
*/
|
|
64
|
+
createChart(config) {
|
|
65
|
+
return new Recharts(config);
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create a live editor instance
|
|
70
|
+
* @param {Object} config - Editor configuration
|
|
71
|
+
* @returns {LiveEditor} LiveEditor instance
|
|
72
|
+
*/
|
|
73
|
+
createEditor(config) {
|
|
74
|
+
return new LiveEditor(config);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default VisualifyCore;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docsify Plugin Entry Point
|
|
3
|
+
* @description Lightweight bundle for Docsify integration
|
|
4
|
+
* Exports only the charting capabilities needed for documentation
|
|
5
|
+
* Global name: VisualifyDocs
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import DocsifyPlugin from '../docsify/plugin';
|
|
9
|
+
import { processMarkdown, processVisualifyBlocks, extractConfigs } from '../docsify/markdown';
|
|
10
|
+
import Recharts from '../core/recharts';
|
|
11
|
+
import LiveEditor from '../core/liveEditor';
|
|
12
|
+
import { VisualifyProvider } from '../core/appContext';
|
|
13
|
+
|
|
14
|
+
// Re-export shared components for docs usage
|
|
15
|
+
export { Recharts, LiveEditor, VisualifyProvider };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Docsify plugin initialization
|
|
19
|
+
* Registers Visualify components as Docsify plugins
|
|
20
|
+
*/
|
|
21
|
+
function install(hook, vm) {
|
|
22
|
+
hook.init(function () {
|
|
23
|
+
// Initialize any required setup before Docsify starts
|
|
24
|
+
console.log('[VisualifyDocs] Initializing Docsify plugin...');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
hook.mounted(function () {
|
|
28
|
+
// Auto-mount charts with data-visualify attribute after each page mount
|
|
29
|
+
const chartElements = document.querySelectorAll('[data-visualify]');
|
|
30
|
+
chartElements.forEach((el) => {
|
|
31
|
+
try {
|
|
32
|
+
const config = JSON.parse(el.dataset.visualify || '{}');
|
|
33
|
+
const chart = new Recharts(config);
|
|
34
|
+
chart.mount(el);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.error('[VisualifyDocs] Failed to mount chart:', e);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
hook.doneEach(function () {
|
|
42
|
+
// Re-mount charts after each navigation (SPA behavior)
|
|
43
|
+
const chartElements = document.querySelectorAll('[data-visualify]');
|
|
44
|
+
chartElements.forEach((el) => {
|
|
45
|
+
// Skip if already mounted
|
|
46
|
+
if (el.dataset.visualifyMounted) return;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const config = JSON.parse(el.dataset.visualify || '{}');
|
|
50
|
+
const chart = new Recharts(config);
|
|
51
|
+
chart.mount(el);
|
|
52
|
+
el.dataset.visualifyMounted = 'true';
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.error('[VisualifyDocs] Failed to mount chart:', e);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Global install function for UMD builds
|
|
62
|
+
* Attaches to window.VisualifyDocs
|
|
63
|
+
*/
|
|
64
|
+
const VisualifyDocs = {
|
|
65
|
+
// Core charting classes
|
|
66
|
+
Recharts,
|
|
67
|
+
LiveEditor,
|
|
68
|
+
|
|
69
|
+
// Provider for React context
|
|
70
|
+
VisualifyProvider,
|
|
71
|
+
|
|
72
|
+
// Docsify plugin
|
|
73
|
+
plugin: DocsifyPlugin,
|
|
74
|
+
|
|
75
|
+
// Markdown processing utilities
|
|
76
|
+
markdown: {
|
|
77
|
+
process: processMarkdown,
|
|
78
|
+
processBlocks: processVisualifyBlocks,
|
|
79
|
+
extractConfigs,
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
// Legacy install function for backwards compatibility
|
|
83
|
+
install,
|
|
84
|
+
|
|
85
|
+
// Version info (replaced during build)
|
|
86
|
+
version: process.env.VISUALIFY_VERSION || 'dev',
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Create a chart instance
|
|
90
|
+
* @param {Object} config - Chart configuration
|
|
91
|
+
* @returns {Recharts} Recharts instance
|
|
92
|
+
*/
|
|
93
|
+
createChart(config) {
|
|
94
|
+
return new Recharts(config);
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Create a live editor instance
|
|
99
|
+
* @param {Object} config - Editor configuration
|
|
100
|
+
* @returns {LiveEditor} LiveEditor instance
|
|
101
|
+
*/
|
|
102
|
+
createEditor(config) {
|
|
103
|
+
return new LiveEditor(config);
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Mount all charts with data-visualify attribute in container
|
|
108
|
+
* @param {string|Element} container - Container element or selector
|
|
109
|
+
*/
|
|
110
|
+
mountAll(container = document) {
|
|
111
|
+
const root = typeof container === 'string'
|
|
112
|
+
? document.querySelector(container)
|
|
113
|
+
: container;
|
|
114
|
+
|
|
115
|
+
if (!root) {
|
|
116
|
+
console.error('[VisualifyDocs] Container not found:', container);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const chartElements = root.querySelectorAll('[data-visualify]');
|
|
121
|
+
chartElements.forEach((el) => {
|
|
122
|
+
// Skip if already mounted
|
|
123
|
+
if (el.dataset.visualifyMounted) return;
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
const config = JSON.parse(el.dataset.visualify || '{}');
|
|
127
|
+
const chart = new Recharts(config);
|
|
128
|
+
chart.mount(el);
|
|
129
|
+
el.dataset.visualifyMounted = 'true';
|
|
130
|
+
} catch (e) {
|
|
131
|
+
console.error('[VisualifyDocs] Failed to mount chart:', e);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Process visualify code blocks in markdown content
|
|
138
|
+
* @param {string} content - Markdown content
|
|
139
|
+
* @returns {string} HTML with visualify charts
|
|
140
|
+
*/
|
|
141
|
+
processMarkdown(content) {
|
|
142
|
+
return processVisualifyBlocks(content);
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Auto-install if Docsify is present
|
|
147
|
+
if (typeof window !== 'undefined' && window.$docsify) {
|
|
148
|
+
window.$docsify.plugins = [].concat(
|
|
149
|
+
window.$docsify.plugins || [],
|
|
150
|
+
DocsifyPlugin.install
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export default VisualifyDocs;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page Mode Entry Point
|
|
3
|
+
* @description Full page mode bundle with all portal/application components
|
|
4
|
+
* Loaded on demand when mode is 'pages' or standalone portal usage
|
|
5
|
+
* Global name: VisualifyPages
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import CreateApp from '../core/visualify';
|
|
9
|
+
|
|
10
|
+
// Page components
|
|
11
|
+
export { default as JsonPage } from '../core/pages/jsonPage';
|
|
12
|
+
export { default as LoadingPage } from '../core/pages/loading';
|
|
13
|
+
export { default as ErrorPage } from '../core/pages/error';
|
|
14
|
+
export { default as NotFoundPage } from '../core/pages/404';
|
|
15
|
+
|
|
16
|
+
// Layout widgets
|
|
17
|
+
export { default as Layout } from '../core/widgets/layout';
|
|
18
|
+
export { default as Header } from '../core/widgets/header';
|
|
19
|
+
export { default as Footer } from '../core/widgets/footer';
|
|
20
|
+
export { default as Controller } from '../core/widgets/controller';
|
|
21
|
+
export { default as GridLayout } from '../core/widgets/layout/Grid';
|
|
22
|
+
export { default as Mapping } from '../core/widgets/mapping';
|
|
23
|
+
|
|
24
|
+
// Visualization components (page mode specific)
|
|
25
|
+
export { default as Scatter } from '../core/components/Scatter';
|
|
26
|
+
export { default as ScatterBio } from '../core/components/ScatterBio';
|
|
27
|
+
export { default as ScatterL } from '../core/components/scatterL';
|
|
28
|
+
export { default as VisiumPlot } from '../core/components/VisiumPlot';
|
|
29
|
+
export { default as Visium } from '../core/components/visium';
|
|
30
|
+
export { default as DotPlot } from '../core/components/dotplot';
|
|
31
|
+
export { default as Macaron } from '../core/components/macaron';
|
|
32
|
+
export { default as Ratio } from '../core/components/ratio';
|
|
33
|
+
export { default as Timeline } from '../core/components/timeline';
|
|
34
|
+
export { default as Selection } from '../core/components/selection';
|
|
35
|
+
export { default as SearchBar } from '../core/components/searchbar';
|
|
36
|
+
export { default as Browser } from '../core/components/browser';
|
|
37
|
+
export { default as List } from '../core/components/list';
|
|
38
|
+
export { default as Html } from '../core/components/html';
|
|
39
|
+
export { default as Markdown } from '../core/components/markdown';
|
|
40
|
+
|
|
41
|
+
// Router components
|
|
42
|
+
export { default as JsonRouter } from '../core/router/jsonRouter';
|
|
43
|
+
export * from '../core/router/alias';
|
|
44
|
+
|
|
45
|
+
// Data fetching utilities
|
|
46
|
+
export { default as fetchData } from '../core/fetch/fetch';
|
|
47
|
+
export { default as condFetch } from '../core/fetch/condfetch';
|
|
48
|
+
export { default as vfetch } from '../core/fetch/vfetch';
|
|
49
|
+
export { default as jsonFetch } from '../core/fetch/json';
|
|
50
|
+
|
|
51
|
+
// Plotly support
|
|
52
|
+
export { default as Replotly } from '../core/modules/replotly';
|
|
53
|
+
export * from '../core/parser/plotly.data';
|
|
54
|
+
export * from '../core/parser/plotly.layout';
|
|
55
|
+
export * from '../core/parser/plotly.config';
|
|
56
|
+
export * from '../core/parser/plotly.violin';
|
|
57
|
+
|
|
58
|
+
// Data parser (for page mode API fetching)
|
|
59
|
+
export { default as fetchDataParser } from '../core/parser/echart.parser';
|
|
60
|
+
export * from '../core/parser/echart.parser';
|
|
61
|
+
export * from '../core/parser/echart.hilbert';
|
|
62
|
+
|
|
63
|
+
// Web vitals
|
|
64
|
+
export { default as reportWebVitals } from '../_utils/reportWebVitals';
|
|
65
|
+
|
|
66
|
+
// Re-export CreateApp
|
|
67
|
+
export { CreateApp };
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* VisualifyPages namespace
|
|
71
|
+
* Full page mode application bundle
|
|
72
|
+
*/
|
|
73
|
+
const VisualifyPages = {
|
|
74
|
+
version: process.env.VISUALIFY_VERSION || 'dev',
|
|
75
|
+
|
|
76
|
+
// Core application creator
|
|
77
|
+
createApp: CreateApp,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Initialize page mode application
|
|
81
|
+
* @param {Object} config - Application configuration
|
|
82
|
+
*/
|
|
83
|
+
init(config) {
|
|
84
|
+
if (!config) {
|
|
85
|
+
throw new Error('[VisualifyPages] Configuration object is required');
|
|
86
|
+
}
|
|
87
|
+
config.mode = config.mode || 'pages';
|
|
88
|
+
CreateApp(config);
|
|
89
|
+
console.log(`[VisualifyPages] v${this.version} initialized`);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default VisualifyPages;
|