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
package/src/core/recharts.js
CHANGED
|
@@ -1,62 +1,361 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
-
* @Date : 2023-11-29 16:02:42
|
|
4
|
-
* @FilePath : /visualifyjs/src/core/recharts.js
|
|
5
|
-
* @Description :
|
|
6
|
-
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
-
*/
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { createRoot } from 'react-dom/client';
|
|
10
|
-
import EChartSwitcher from './modules/echartswitcher';
|
|
11
|
-
import { VisualifyProvider } from './appContext';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
/*
|
|
2
|
+
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
+
* @Date : 2023-11-29 16:02:42
|
|
4
|
+
* @FilePath : /visualifyjs/src/core/recharts.js
|
|
5
|
+
* @Description :
|
|
6
|
+
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
+
*/
|
|
8
|
+
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
|
9
|
+
import { createRoot } from 'react-dom/client';
|
|
10
|
+
import EChartSwitcher from './modules/echartswitcher';
|
|
11
|
+
import { VisualifyProvider } from './appContext';
|
|
12
|
+
import { initHMR, useHMR, preserveChartState, restoreChartState } from './hmr-client';
|
|
13
|
+
|
|
14
|
+
// Import 3D components for docs mode support
|
|
15
|
+
import Scatter3D from './components/Scatter3D';
|
|
16
|
+
import Bar3D from './components/Bar3D';
|
|
17
|
+
import Surface3D from './components/Surface3D';
|
|
18
|
+
import Line3D from './components/Line3D';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Map of 3D chart types to their components
|
|
22
|
+
* @type {Object<string, React.Component>}
|
|
23
|
+
*/
|
|
24
|
+
const CHART_3D_COMPONENTS = {
|
|
25
|
+
scatter3d: Scatter3D,
|
|
26
|
+
bar3d: Bar3D,
|
|
27
|
+
surface3d: Surface3D,
|
|
28
|
+
line3d: Line3D,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if a chart type is a 3D chart
|
|
33
|
+
* @param {string} type - Chart type from config
|
|
34
|
+
* @returns {boolean} True if 3D chart type
|
|
35
|
+
*/
|
|
36
|
+
function is3DChartType(type) {
|
|
37
|
+
if (!type) return false;
|
|
38
|
+
const normalizedType = type.toLowerCase();
|
|
39
|
+
return Object.keys(CHART_3D_COMPONENTS).includes(normalizedType);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Global registry of chart instances for HMR state preservation
|
|
44
|
+
* @type {Map<string, Object>}
|
|
45
|
+
*/
|
|
46
|
+
const chartRegistry = new Map();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Chart wrapper component with HMR support
|
|
50
|
+
* Renders either standard ECharts or 3D components based on config type
|
|
51
|
+
* @param {Object} props - Component props
|
|
52
|
+
* @param {Object} props.config - Chart configuration
|
|
53
|
+
* @param {Object} [props.parser] - Data parser
|
|
54
|
+
* @param {Object} [props.advanced] - Advanced options
|
|
55
|
+
* @param {string} [props.chartId] - Unique chart identifier
|
|
56
|
+
*/
|
|
57
|
+
function ChartWithHMR({ config, parser, advanced, chartId }) {
|
|
58
|
+
const chartRef = useRef(null);
|
|
59
|
+
const [currentConfig, setCurrentConfig] = useState(config);
|
|
60
|
+
const preservedStateRef = useRef(null);
|
|
61
|
+
|
|
62
|
+
// Determine if this is a 3D chart
|
|
63
|
+
const is3D = is3DChartType(currentConfig.type);
|
|
64
|
+
|
|
65
|
+
// Preserve chart state before updates
|
|
66
|
+
const preserveState = useCallback(() => {
|
|
67
|
+
if (chartRef.current) {
|
|
68
|
+
const instance = chartRef.current.getEchartsInstance?.() || chartRef.current;
|
|
69
|
+
preservedStateRef.current = preserveChartState(instance);
|
|
70
|
+
|
|
71
|
+
// Also store in global registry
|
|
72
|
+
if (chartId) {
|
|
73
|
+
chartRegistry.set(chartId, preservedStateRef.current);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return preservedStateRef.current;
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}, [chartId]);
|
|
80
|
+
|
|
81
|
+
// Setup HMR integration
|
|
82
|
+
useHMR({
|
|
83
|
+
configType: 'component',
|
|
84
|
+
onUpdate: (update) => {
|
|
85
|
+
if (update.config) {
|
|
86
|
+
// Preserve current state before updating
|
|
87
|
+
preserveState();
|
|
88
|
+
|
|
89
|
+
// Update config
|
|
90
|
+
setCurrentConfig(update.config);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
onError: (error) => {
|
|
94
|
+
console.error('[Recharts] HMR error:', error.message);
|
|
95
|
+
},
|
|
96
|
+
preserveState,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Restore state after config update
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (preservedStateRef.current && chartRef.current) {
|
|
102
|
+
// Small delay to ensure chart is rendered
|
|
103
|
+
const timer = setTimeout(() => {
|
|
104
|
+
const instance = chartRef.current.getEchartsInstance?.() || chartRef.current;
|
|
105
|
+
restoreChartState(instance, preservedStateRef.current);
|
|
106
|
+
}, 100);
|
|
107
|
+
|
|
108
|
+
return () => clearTimeout(timer);
|
|
109
|
+
}
|
|
110
|
+
}, [currentConfig]);
|
|
111
|
+
|
|
112
|
+
// Render 3D chart component
|
|
113
|
+
if (is3D) {
|
|
114
|
+
const Component3D = CHART_3D_COMPONENTS[currentConfig.type.toLowerCase()];
|
|
115
|
+
return (
|
|
116
|
+
<Component3D
|
|
117
|
+
ref={chartRef}
|
|
118
|
+
props={{
|
|
119
|
+
config: currentConfig,
|
|
120
|
+
parser: parser,
|
|
121
|
+
advanced: advanced,
|
|
122
|
+
id: chartId,
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Render standard EChart
|
|
129
|
+
return (
|
|
130
|
+
<EChartSwitcher
|
|
131
|
+
ref={chartRef}
|
|
132
|
+
props={{
|
|
133
|
+
config: currentConfig,
|
|
134
|
+
parser: parser,
|
|
135
|
+
advanced: advanced,
|
|
136
|
+
}}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
class Recharts {
|
|
142
|
+
constructor(config = {}) {
|
|
143
|
+
const { el = null, id = null } = config;
|
|
144
|
+
// Default to empty object if nothing is passed
|
|
145
|
+
if (typeof el === 'string') {
|
|
146
|
+
this.selector = document.querySelector(el);
|
|
147
|
+
if (!this.selector) {
|
|
148
|
+
throw new Error(`Element not found with selector: ${el}`);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
this.selector = el;
|
|
152
|
+
}
|
|
153
|
+
const { parser = null, advanced = null, ...rest } = config;
|
|
154
|
+
this.config = rest;
|
|
155
|
+
this.parser = parser;
|
|
156
|
+
this.advanced = advanced;
|
|
157
|
+
this.chartId = id || `chart-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
158
|
+
this.root = null;
|
|
159
|
+
this.isMounted = false;
|
|
160
|
+
|
|
161
|
+
// Initialize HMR if available
|
|
162
|
+
if (typeof window !== 'undefined' && window.__VISUALIFY_HMR__?.enabled) {
|
|
163
|
+
initHMR();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Mount the chart to the DOM
|
|
169
|
+
* @param {string|Element} [selector=this.selector] - Selector or element to mount to
|
|
170
|
+
* @returns {Recharts} This instance for chaining
|
|
171
|
+
*/
|
|
172
|
+
mount(selector = this.selector) {
|
|
173
|
+
const el =
|
|
174
|
+
typeof selector === 'string'
|
|
175
|
+
? document.querySelector(selector)
|
|
176
|
+
: selector;
|
|
177
|
+
|
|
178
|
+
if (!el)
|
|
179
|
+
throw new Error(`Element not found with selector: ${selector}`);
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
// Check for preserved state from HMR
|
|
183
|
+
const preservedState = chartRegistry.get(this.chartId);
|
|
184
|
+
|
|
185
|
+
// Create or reuse root
|
|
186
|
+
if (!this.root) {
|
|
187
|
+
this.root = createRoot(el);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.root.render(
|
|
191
|
+
<VisualifyProvider>
|
|
192
|
+
<ChartWithHMR
|
|
193
|
+
config={this.config}
|
|
194
|
+
parser={this.parser}
|
|
195
|
+
advanced={this.advanced}
|
|
196
|
+
chartId={this.chartId}
|
|
197
|
+
/>
|
|
198
|
+
</VisualifyProvider>,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
this.isMounted = true;
|
|
202
|
+
|
|
203
|
+
// Register for HMR updates
|
|
204
|
+
this.registerHMR();
|
|
205
|
+
} catch (e) {
|
|
206
|
+
console.error('Error mounting chart:', e);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Unmount the chart and cleanup
|
|
214
|
+
* @returns {Recharts} This instance for chaining
|
|
215
|
+
*/
|
|
216
|
+
unmount() {
|
|
217
|
+
if (this.root) {
|
|
218
|
+
// Preserve state before unmounting
|
|
219
|
+
this.preserveState();
|
|
220
|
+
|
|
221
|
+
this.root.unmount();
|
|
222
|
+
this.root = null;
|
|
223
|
+
this.isMounted = false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Unregister from HMR
|
|
227
|
+
this.unregisterHMR();
|
|
228
|
+
|
|
229
|
+
return this;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Update the chart configuration (for HMR)
|
|
234
|
+
* @param {Object} newConfig - New configuration
|
|
235
|
+
* @returns {Recharts} This instance for chaining
|
|
236
|
+
*/
|
|
237
|
+
update(newConfig) {
|
|
238
|
+
// Preserve current state
|
|
239
|
+
this.preserveState();
|
|
240
|
+
|
|
241
|
+
// Update config
|
|
242
|
+
const { parser, advanced, ...rest } = newConfig;
|
|
243
|
+
this.config = { ...this.config, ...rest };
|
|
244
|
+
if (parser) this.parser = parser;
|
|
245
|
+
if (advanced) this.advanced = advanced;
|
|
246
|
+
|
|
247
|
+
// Re-mount if already mounted
|
|
248
|
+
if (this.isMounted) {
|
|
249
|
+
this.mount();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return this;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Preserve the current chart state
|
|
257
|
+
* @returns {Object|null} The preserved state
|
|
258
|
+
*/
|
|
259
|
+
preserveState() {
|
|
260
|
+
// State is preserved in the ChartWithHMR component
|
|
261
|
+
// This method is for external access
|
|
262
|
+
const state = chartRegistry.get(this.chartId);
|
|
263
|
+
return state || null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Restore chart state
|
|
268
|
+
* @param {Object} state - State to restore
|
|
269
|
+
* @returns {Recharts} This instance for chaining
|
|
270
|
+
*/
|
|
271
|
+
restoreState(state) {
|
|
272
|
+
if (state) {
|
|
273
|
+
chartRegistry.set(this.chartId, state);
|
|
274
|
+
}
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Register this chart for HMR updates
|
|
280
|
+
* @private
|
|
281
|
+
*/
|
|
282
|
+
registerHMR() {
|
|
283
|
+
if (typeof window === 'undefined') return;
|
|
284
|
+
|
|
285
|
+
// Store reference for HMR updates
|
|
286
|
+
if (!window.__VISUALIFY_CHARTS__) {
|
|
287
|
+
window.__VISUALIFY_CHARTS__ = new Map();
|
|
288
|
+
}
|
|
289
|
+
window.__VISUALIFY_CHARTS__.set(this.chartId, this);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Unregister this chart from HMR updates
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
unregisterHMR() {
|
|
297
|
+
if (typeof window === 'undefined') return;
|
|
298
|
+
|
|
299
|
+
window.__VISUALIFY_CHARTS__?.delete(this.chartId);
|
|
300
|
+
chartRegistry.delete(this.chartId);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Get the chart ID
|
|
305
|
+
* @returns {string} The chart ID
|
|
306
|
+
*/
|
|
307
|
+
getId() {
|
|
308
|
+
return this.chartId;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Check if the chart is mounted
|
|
313
|
+
* @returns {boolean} Whether the chart is mounted
|
|
314
|
+
*/
|
|
315
|
+
getIsMounted() {
|
|
316
|
+
return this.isMounted;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Reload all mounted charts (for HMR)
|
|
322
|
+
* @param {Object} [configUpdate] - Optional configuration update
|
|
323
|
+
*/
|
|
324
|
+
export function reloadAllCharts(configUpdate) {
|
|
325
|
+
if (typeof window === 'undefined') return;
|
|
326
|
+
|
|
327
|
+
const charts = window.__VISUALIFY_CHARTS__;
|
|
328
|
+
if (!charts) return;
|
|
329
|
+
|
|
330
|
+
charts.forEach((chart) => {
|
|
331
|
+
if (chart.getIsMounted() && configUpdate) {
|
|
332
|
+
chart.update(configUpdate);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Preserve state of all charts
|
|
339
|
+
* @returns {Map<string, Object>} Map of chart IDs to preserved states
|
|
340
|
+
*/
|
|
341
|
+
export function preserveAllChartStates() {
|
|
342
|
+
const states = new Map();
|
|
343
|
+
|
|
344
|
+
chartRegistry.forEach((state, chartId) => {
|
|
345
|
+
states.set(chartId, state);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
return states;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Restore state to all charts
|
|
353
|
+
* @param {Map<string, Object>} states - Map of chart IDs to states
|
|
354
|
+
*/
|
|
355
|
+
export function restoreAllChartStates(states) {
|
|
356
|
+
states.forEach((state, chartId) => {
|
|
357
|
+
chartRegistry.set(chartId, state);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export default Recharts;
|
package/src/core/router/alias.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
-
* @Date : 2023-12-04 12:47:02
|
|
4
|
-
* @FilePath : /visualifyjs/src/core/router/alias.js
|
|
5
|
-
* @Description :
|
|
6
|
-
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
-
*/
|
|
8
|
-
import { Navigate, useLocation } from 'react-router-dom';
|
|
9
|
-
|
|
10
|
-
const AliasRoute = ({ alias, children }) => {
|
|
11
|
-
const location = useLocation();
|
|
12
|
-
|
|
13
|
-
for (const pattern in alias) {
|
|
14
|
-
const regex = new RegExp(pattern);
|
|
15
|
-
if (regex.test(location.pathname)) {
|
|
16
|
-
const target = alias[pattern];
|
|
17
|
-
|
|
18
|
-
// Check if the target is defined and is a string
|
|
19
|
-
if (typeof target === 'string') {
|
|
20
|
-
// Check if target is a URL or a path
|
|
21
|
-
if (
|
|
22
|
-
target.startsWith('http://') ||
|
|
23
|
-
target.startsWith('https://')
|
|
24
|
-
) {
|
|
25
|
-
window.location.href = target;
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Redirect to the matched route
|
|
30
|
-
const newPath = location.pathname.replace(regex, target);
|
|
31
|
-
return (
|
|
32
|
-
<Navigate
|
|
33
|
-
to={newPath}
|
|
34
|
-
replace
|
|
35
|
-
/>
|
|
36
|
-
);
|
|
37
|
-
} else {
|
|
38
|
-
console.error(
|
|
39
|
-
`Alias target for pattern '${pattern}' is not defined or not a string.`,
|
|
40
|
-
);
|
|
41
|
-
continue; // Skip to the next pattern
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return children;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export default AliasRoute;
|
|
1
|
+
/*
|
|
2
|
+
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
+
* @Date : 2023-12-04 12:47:02
|
|
4
|
+
* @FilePath : /visualifyjs/src/core/router/alias.js
|
|
5
|
+
* @Description :
|
|
6
|
+
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
+
*/
|
|
8
|
+
import { Navigate, useLocation } from 'react-router-dom';
|
|
9
|
+
|
|
10
|
+
const AliasRoute = ({ alias, children }) => {
|
|
11
|
+
const location = useLocation();
|
|
12
|
+
|
|
13
|
+
for (const pattern in alias) {
|
|
14
|
+
const regex = new RegExp(pattern);
|
|
15
|
+
if (regex.test(location.pathname)) {
|
|
16
|
+
const target = alias[pattern];
|
|
17
|
+
|
|
18
|
+
// Check if the target is defined and is a string
|
|
19
|
+
if (typeof target === 'string') {
|
|
20
|
+
// Check if target is a URL or a path
|
|
21
|
+
if (
|
|
22
|
+
target.startsWith('http://') ||
|
|
23
|
+
target.startsWith('https://')
|
|
24
|
+
) {
|
|
25
|
+
window.location.href = target;
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Redirect to the matched route
|
|
30
|
+
const newPath = location.pathname.replace(regex, target);
|
|
31
|
+
return (
|
|
32
|
+
<Navigate
|
|
33
|
+
to={newPath}
|
|
34
|
+
replace
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
console.error(
|
|
39
|
+
`Alias target for pattern '${pattern}' is not defined or not a string.`,
|
|
40
|
+
);
|
|
41
|
+
continue; // Skip to the next pattern
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return children;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default AliasRoute;
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
-
* @Date : 2023-11-29 21:58:14
|
|
4
|
-
* @FilePath : /visualifyjs/src/core/router/jsonRouter.js
|
|
5
|
-
* @Description :
|
|
6
|
-
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
-
*/
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { HashRouter, Route, Routes } from 'react-router-dom';
|
|
10
|
-
import AliasRoute from './alias';
|
|
11
|
-
|
|
12
|
-
function JsonRouter({ config, children }) {
|
|
13
|
-
const { alias } = config;
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<HashRouter>
|
|
17
|
-
<Routes>
|
|
18
|
-
<Route
|
|
19
|
-
path='/'
|
|
20
|
-
element={children}
|
|
21
|
-
/>
|
|
22
|
-
<Route
|
|
23
|
-
path='/*'
|
|
24
|
-
element={<AliasRoute alias={alias}>{children}</AliasRoute>}
|
|
25
|
-
/>
|
|
26
|
-
</Routes>
|
|
27
|
-
</HashRouter>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default JsonRouter;
|
|
1
|
+
/*
|
|
2
|
+
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
+
* @Date : 2023-11-29 21:58:14
|
|
4
|
+
* @FilePath : /visualifyjs/src/core/router/jsonRouter.js
|
|
5
|
+
* @Description :
|
|
6
|
+
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
+
*/
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { HashRouter, Route, Routes } from 'react-router-dom';
|
|
10
|
+
import AliasRoute from './alias';
|
|
11
|
+
|
|
12
|
+
function JsonRouter({ config, children }) {
|
|
13
|
+
const { alias } = config;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<HashRouter>
|
|
17
|
+
<Routes>
|
|
18
|
+
<Route
|
|
19
|
+
path='/'
|
|
20
|
+
element={children}
|
|
21
|
+
/>
|
|
22
|
+
<Route
|
|
23
|
+
path='/*'
|
|
24
|
+
element={<AliasRoute alias={alias}>{children}</AliasRoute>}
|
|
25
|
+
/>
|
|
26
|
+
</Routes>
|
|
27
|
+
</HashRouter>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default JsonRouter;
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
-
* @Date : 2023-11-29 22:03:28
|
|
4
|
-
* @FilePath : /visualifyjs/src/core/themes/modern.js
|
|
5
|
-
* @Description :
|
|
6
|
-
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import Vheader from '../widgets/header';
|
|
11
|
-
import Vfooter from '../widgets/footer';
|
|
12
|
-
import { Container } from 'react-bootstrap';
|
|
13
|
-
import JsonPage from '../pages/jsonPage';
|
|
14
|
-
|
|
15
|
-
import '../../_css/modern.css';
|
|
16
|
-
|
|
17
|
-
function Modern({ config, children }) {
|
|
18
|
-
//console.log('Modern config', config);
|
|
19
|
-
const { homepage = 'home.json' } = config;
|
|
20
|
-
return (
|
|
21
|
-
<>
|
|
22
|
-
<Vheader config={config} />
|
|
23
|
-
<Container className='text-center'>
|
|
24
|
-
<JsonPage homepage={homepage} />
|
|
25
|
-
{children}
|
|
26
|
-
</Container>
|
|
27
|
-
<Vfooter config={config} />
|
|
28
|
-
</>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export default Modern;
|
|
1
|
+
/*
|
|
2
|
+
* @Author : Lihao leolihao@arizona.edu
|
|
3
|
+
* @Date : 2023-11-29 22:03:28
|
|
4
|
+
* @FilePath : /visualifyjs/src/core/themes/modern.js
|
|
5
|
+
* @Description :
|
|
6
|
+
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import Vheader from '../widgets/header';
|
|
11
|
+
import Vfooter from '../widgets/footer';
|
|
12
|
+
import { Container } from 'react-bootstrap';
|
|
13
|
+
import JsonPage from '../pages/jsonPage';
|
|
14
|
+
|
|
15
|
+
import '../../_css/modern.css';
|
|
16
|
+
|
|
17
|
+
function Modern({ config, children }) {
|
|
18
|
+
//console.log('Modern config', config);
|
|
19
|
+
const { homepage = 'home.json' } = config;
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<Vheader config={config} />
|
|
23
|
+
<Container className='text-center'>
|
|
24
|
+
<JsonPage homepage={homepage} />
|
|
25
|
+
{children}
|
|
26
|
+
</Container>
|
|
27
|
+
<Vfooter config={config} />
|
|
28
|
+
</>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default Modern;
|