visualifyjs 2.5.3-2.dev → 2.5.3-9-dev
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.
Potentially problematic release.
This version of visualifyjs might be problematic. Click here for more details.
- package/.github/workflows/{static.yml.bak → build.yaml} +51 -51
- package/LICENSE +674 -674
- package/README.md +40 -58
- package/config-overrides.js +31 -31
- package/dist/visualify.js +3 -3
- package/docs/CLI.md +15 -0
- package/docs/{docs/README.md → README.md} +41 -65
- package/docs/{docs/Rechart → Rechart}/bar.md +190 -190
- package/docs/{docs/Rechart → Rechart}/funnel.md +193 -241
- package/docs/{docs/Rechart → Rechart}/line.md +355 -355
- package/docs/{docs/Rechart → Rechart}/pie.md +225 -225
- package/docs/{docs/Rechart → Rechart}/radar.md +253 -253
- package/docs/{docs/_404.md → _404.md} +51 -51
- package/docs/{docs/_coverpage.md → _coverpage.md} +11 -11
- package/docs/{docs/_sidebar.md → _sidebar.md} +42 -44
- package/docs/{docs/components → components}/dotBio.md +34 -34
- package/docs/{docs/components → components}/echart.md +82 -82
- package/docs/{docs/components → components}/html.md +34 -34
- package/docs/{docs/components → components}/macaron.md +145 -145
- package/docs/components/markdown.md +0 -0
- package/docs/{docs/components → components}/more.md +142 -142
- package/docs/{docs/components → components}/plotly.md +62 -62
- package/docs/{docs/components → components}/scatterL.md +70 -70
- package/docs/{docs/components → components}/visium.md +56 -56
- package/docs/{docs/configuration.md → configuration.md} +123 -121
- package/docs/{docs/deploy.md → deploy.md} +23 -31
- package/docs/index.html +70 -70
- package/docs/log.md +1 -0
- package/docs/manifest.json +23 -23
- package/docs/{docs/more-pages.md → more-pages.md} +23 -23
- package/docs/{docs/quickstart.md → quickstart.md} +115 -124
- package/docs/{docs/rechart-attributes.md → rechart-attributes.md} +74 -74
- package/docs/{docs/rechart-basic-usage.md → rechart-basic-usage.md} +162 -162
- 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 +25 -25
- package/docs/static/js/configuration.js +448 -448
- package/docs/static/js/visualify.js +24 -23
- package/docs/theme.md +3 -0
- package/package.json +74 -83
- package/rollup.config.mjs +75 -75
- 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 +24 -24
- 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/core/appContext.js +27 -27
- package/src/core/components/Scatter.js +188 -188
- package/src/core/components/ScatterBio.js +572 -572
- package/src/core/components/VisiumPlot.js +165 -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 +201 -201
- package/src/core/components/markdown.js +56 -56
- package/src/core/components/parser.scatterBio.js +579 -587
- package/src/core/components/ratio.js +80 -80
- package/src/core/components/scatterL.js +173 -173
- package/src/core/components/searchbar.js +131 -131
- package/src/core/components/selection.js +193 -193
- package/src/core/components/timeline.js +281 -281
- package/src/core/components/visium.js +97 -97
- 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/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/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 +71 -71
- package/src/core/modules/echartsUtils.js +43 -43
- package/src/core/modules/echartswitcher.js +152 -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 +71 -71
- 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 +183 -183
- package/src/core/parser/echart.features.js +125 -125
- package/src/core/parser/echart.general.js +143 -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 +62 -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 +47 -47
- package/src/core/widgets/circularProgress.js +23 -23
- package/src/core/widgets/controller.js +83 -83
- package/src/core/widgets/errorBoundary.js +36 -36
- package/src/core/widgets/footer.js +177 -177
- package/src/core/widgets/header.js +234 -234
- package/src/core/widgets/layout/Grid.js +31 -31
- package/src/core/widgets/layout.js +36 -36
- package/src/core/widgets/mapping.js +42 -42
- package/src/index.js +62 -62
- package/src/setupTests.js +5 -5
- package/docs/docs/CLI.md +0 -34
- package/docs/docs/Rechart/scatter.md +0 -298
- package/docs/docs/log.md +0 -9
- package/docs/docs/static/logo/favicon.ico +0 -0
- package/docs/docs/static/logo/logo_128x128.png +0 -0
- package/docs/docs/static/logo/logo_192x192.png +0 -0
- package/docs/docs/static/logo/logo_256x256.png +0 -0
- package/docs/docs/static/logo/logo_512x512.png +0 -0
- package/docs/docs/static/logo/logo_64x64.png +0 -0
- package/docs/docs/theme.md +0 -5
- /package/docs/{docs/Rechart → Rechart}/geo.md +0 -0
- /package/docs/{docs/Rechart → Rechart}/liquidfill.md +0 -0
- /package/docs/{docs/Rechart → Rechart}/polar.md +0 -0
- /package/docs/{docs/Rechart → Rechart}/sankey.md +0 -0
- /package/docs/{docs/Rechart/sunburst.md → Rechart/scatter.md} +0 -0
- /package/docs/{docs/Rechart/tree.md → Rechart/sunburst.md} +0 -0
- /package/docs/{docs/Rechart/wordcloud.md → Rechart/tree.md} +0 -0
- /package/docs/{docs/components/markdown.md → Rechart/wordcloud.md} +0 -0
- /package/docs/{docs/static → static}/_images/deploy-github-pages.png +0 -0
@@ -1,201 +1,201 @@
|
|
1
|
-
import React, { useState, useEffect, useMemo } from 'react';
|
2
|
-
import { useAppContext } from '../appContext';
|
3
|
-
import ReCharts from '../modules/echarts';
|
4
|
-
|
5
|
-
function processData(
|
6
|
-
nodes,
|
7
|
-
selected,
|
8
|
-
_symbolSize,
|
9
|
-
maxValue,
|
10
|
-
inner_color,
|
11
|
-
unclickable,
|
12
|
-
) {
|
13
|
-
const { nodes: selectedNodes, category: selectedCategory } = selected;
|
14
|
-
|
15
|
-
return nodes.nodes.map((node) => {
|
16
|
-
const symbolSize =
|
17
|
-
typeof _symbolSize === 'number'
|
18
|
-
? _symbolSize
|
19
|
-
: typeof _symbolSize === 'string'
|
20
|
-
? _symbolSize === 'default'
|
21
|
-
? (6 - node.category) * 6
|
22
|
-
: 10 + (parseFloat(node[_symbolSize]) / maxValue) * 30 ||
|
23
|
-
(6 - node.category) * 6
|
24
|
-
: (6 - node.category) * 6; // Fallback to default
|
25
|
-
|
26
|
-
const isSelected = selectedNodes.includes(node.name);
|
27
|
-
const isSameCategory = node.category === selectedCategory;
|
28
|
-
const isOriginalState =
|
29
|
-
selectedCategory === null && selectedNodes.length === 0;
|
30
|
-
const isUnclickable =
|
31
|
-
unclickable.includes(node.name) ||
|
32
|
-
unclickable.includes(node.category);
|
33
|
-
const opacity = isUnclickable
|
34
|
-
? 0.8
|
35
|
-
: isOriginalState
|
36
|
-
? 1
|
37
|
-
: isSelected
|
38
|
-
? 1
|
39
|
-
: isSameCategory
|
40
|
-
? 1
|
41
|
-
: 0.2;
|
42
|
-
const color = isUnclickable
|
43
|
-
? 'gray'
|
44
|
-
: isOriginalState
|
45
|
-
? `hsl(${node.category * 110}, 50%, 50%)`
|
46
|
-
: isSelected
|
47
|
-
? inner_color.selected ?? 'red'
|
48
|
-
: isSameCategory
|
49
|
-
? `hsl(${node.category * 100}, 50%, 50%)`
|
50
|
-
: inner_color.unselectable ?? 'grey';
|
51
|
-
|
52
|
-
return {
|
53
|
-
...node,
|
54
|
-
symbolSize,
|
55
|
-
itemStyle: {
|
56
|
-
color,
|
57
|
-
opacity,
|
58
|
-
},
|
59
|
-
emphasis: {
|
60
|
-
focus: 'self',
|
61
|
-
itemStyle: {
|
62
|
-
color,
|
63
|
-
opacity,
|
64
|
-
},
|
65
|
-
label: {
|
66
|
-
position: 'insideTop',
|
67
|
-
show: true, // Show label
|
68
|
-
},
|
69
|
-
},
|
70
|
-
};
|
71
|
-
});
|
72
|
-
}
|
73
|
-
|
74
|
-
function Macaron({ props, style }) {
|
75
|
-
const { debug, style: _style, className } = props;
|
76
|
-
const { id, title, data } = props;
|
77
|
-
|
78
|
-
const {
|
79
|
-
animation = false,
|
80
|
-
draggable = true,
|
81
|
-
repulsion = 100,
|
82
|
-
edgeLength = 40,
|
83
|
-
height: inner_height = '93%',
|
84
|
-
width: inner_width = '100%',
|
85
|
-
unclickable = [],
|
86
|
-
symbolSize: _symbolSize = 'default',
|
87
|
-
color: inner_color = {
|
88
|
-
selected: 'red',
|
89
|
-
unselectable: 'grey',
|
90
|
-
},
|
91
|
-
singleclick = true,
|
92
|
-
} = props.config;
|
93
|
-
|
94
|
-
const [selected, setSelected] = useState({ nodes: [], category: null });
|
95
|
-
const { val = 'vnode' } = props;
|
96
|
-
|
97
|
-
const inner_style = {
|
98
|
-
border: debug ? '1px solid black' : 'none',
|
99
|
-
height: inner_height,
|
100
|
-
width: inner_width,
|
101
|
-
};
|
102
|
-
|
103
|
-
const maxValue = useMemo(() => {
|
104
|
-
const values = data.nodes.map(
|
105
|
-
(node) => parseFloat(node[_symbolSize]) || 50,
|
106
|
-
);
|
107
|
-
return Math.max(...values);
|
108
|
-
}, [data, _symbolSize]);
|
109
|
-
|
110
|
-
const processedData = useMemo(
|
111
|
-
() =>
|
112
|
-
processData(
|
113
|
-
data,
|
114
|
-
selected,
|
115
|
-
_symbolSize,
|
116
|
-
maxValue,
|
117
|
-
inner_color,
|
118
|
-
unclickable,
|
119
|
-
),
|
120
|
-
[data, selected, _symbolSize, maxValue, inner_color, unclickable],
|
121
|
-
);
|
122
|
-
|
123
|
-
const onChartClick = (params) => {
|
124
|
-
const category = params.data.category;
|
125
|
-
const name = params.data.name;
|
126
|
-
if (
|
127
|
-
params.dataType === 'node' &&
|
128
|
-
!unclickable.includes(category) &&
|
129
|
-
!unclickable.includes(name) &&
|
130
|
-
(selected.category === null || category === selected.category)
|
131
|
-
) {
|
132
|
-
let updatedSelectedNodes = [...selected.nodes];
|
133
|
-
let updatedSelectedCategory = selected.category;
|
134
|
-
if (selected.nodes.includes(name)) {
|
135
|
-
updatedSelectedNodes = updatedSelectedNodes.filter(
|
136
|
-
(nodeName) => nodeName !== name,
|
137
|
-
);
|
138
|
-
if (updatedSelectedNodes.length === 0) {
|
139
|
-
updatedSelectedCategory = null;
|
140
|
-
}
|
141
|
-
} else {
|
142
|
-
if (singleclick) updatedSelectedNodes = [name];
|
143
|
-
else updatedSelectedNodes.push(name);
|
144
|
-
updatedSelectedCategory = category;
|
145
|
-
}
|
146
|
-
setSelected({
|
147
|
-
nodes: updatedSelectedNodes,
|
148
|
-
category: updatedSelectedCategory,
|
149
|
-
});
|
150
|
-
}
|
151
|
-
};
|
152
|
-
|
153
|
-
const { setSharedData } = useAppContext();
|
154
|
-
|
155
|
-
useEffect(() => {
|
156
|
-
if (
|
157
|
-
val &&
|
158
|
-
Array.isArray(selected.nodes) &&
|
159
|
-
selected.nodes.length >= 0
|
160
|
-
) {
|
161
|
-
setSharedData((prevSharedData) => ({
|
162
|
-
...prevSharedData,
|
163
|
-
[val]: selected.nodes,
|
164
|
-
}));
|
165
|
-
}
|
166
|
-
}, [selected, val, setSharedData]);
|
167
|
-
|
168
|
-
return (
|
169
|
-
<div
|
170
|
-
key={id}
|
171
|
-
style={{ ...style, ..._style }}
|
172
|
-
className={className}>
|
173
|
-
{title && <h3>{title}</h3>}
|
174
|
-
<ReCharts
|
175
|
-
options={{
|
176
|
-
series: [
|
177
|
-
{
|
178
|
-
type: 'graph',
|
179
|
-
layout: 'force',
|
180
|
-
animation,
|
181
|
-
draggable,
|
182
|
-
label: {
|
183
|
-
position: 'top',
|
184
|
-
formatter: '{b}',
|
185
|
-
show: true,
|
186
|
-
},
|
187
|
-
data: processedData,
|
188
|
-
categories: data.categories,
|
189
|
-
edges: data.edges,
|
190
|
-
force: { repulsion, edgeLength },
|
191
|
-
},
|
192
|
-
],
|
193
|
-
}}
|
194
|
-
style={inner_style}
|
195
|
-
onEvents={{ click: onChartClick }}
|
196
|
-
/>
|
197
|
-
</div>
|
198
|
-
);
|
199
|
-
}
|
200
|
-
|
201
|
-
export default Macaron;
|
1
|
+
import React, { useState, useEffect, useMemo } from 'react';
|
2
|
+
import { useAppContext } from '../appContext';
|
3
|
+
import ReCharts from '../modules/echarts';
|
4
|
+
|
5
|
+
function processData(
|
6
|
+
nodes,
|
7
|
+
selected,
|
8
|
+
_symbolSize,
|
9
|
+
maxValue,
|
10
|
+
inner_color,
|
11
|
+
unclickable,
|
12
|
+
) {
|
13
|
+
const { nodes: selectedNodes, category: selectedCategory } = selected;
|
14
|
+
|
15
|
+
return nodes.nodes.map((node) => {
|
16
|
+
const symbolSize =
|
17
|
+
typeof _symbolSize === 'number'
|
18
|
+
? _symbolSize
|
19
|
+
: typeof _symbolSize === 'string'
|
20
|
+
? _symbolSize === 'default'
|
21
|
+
? (6 - node.category) * 6
|
22
|
+
: 10 + (parseFloat(node[_symbolSize]) / maxValue) * 30 ||
|
23
|
+
(6 - node.category) * 6
|
24
|
+
: (6 - node.category) * 6; // Fallback to default
|
25
|
+
|
26
|
+
const isSelected = selectedNodes.includes(node.name);
|
27
|
+
const isSameCategory = node.category === selectedCategory;
|
28
|
+
const isOriginalState =
|
29
|
+
selectedCategory === null && selectedNodes.length === 0;
|
30
|
+
const isUnclickable =
|
31
|
+
unclickable.includes(node.name) ||
|
32
|
+
unclickable.includes(node.category);
|
33
|
+
const opacity = isUnclickable
|
34
|
+
? 0.8
|
35
|
+
: isOriginalState
|
36
|
+
? 1
|
37
|
+
: isSelected
|
38
|
+
? 1
|
39
|
+
: isSameCategory
|
40
|
+
? 1
|
41
|
+
: 0.2;
|
42
|
+
const color = isUnclickable
|
43
|
+
? 'gray'
|
44
|
+
: isOriginalState
|
45
|
+
? `hsl(${node.category * 110}, 50%, 50%)`
|
46
|
+
: isSelected
|
47
|
+
? inner_color.selected ?? 'red'
|
48
|
+
: isSameCategory
|
49
|
+
? `hsl(${node.category * 100}, 50%, 50%)`
|
50
|
+
: inner_color.unselectable ?? 'grey';
|
51
|
+
|
52
|
+
return {
|
53
|
+
...node,
|
54
|
+
symbolSize,
|
55
|
+
itemStyle: {
|
56
|
+
color,
|
57
|
+
opacity,
|
58
|
+
},
|
59
|
+
emphasis: {
|
60
|
+
focus: 'self',
|
61
|
+
itemStyle: {
|
62
|
+
color,
|
63
|
+
opacity,
|
64
|
+
},
|
65
|
+
label: {
|
66
|
+
position: 'insideTop',
|
67
|
+
show: true, // Show label
|
68
|
+
},
|
69
|
+
},
|
70
|
+
};
|
71
|
+
});
|
72
|
+
}
|
73
|
+
|
74
|
+
function Macaron({ props, style }) {
|
75
|
+
const { debug, style: _style, className } = props;
|
76
|
+
const { id, title, data } = props;
|
77
|
+
|
78
|
+
const {
|
79
|
+
animation = false,
|
80
|
+
draggable = true,
|
81
|
+
repulsion = 100,
|
82
|
+
edgeLength = 40,
|
83
|
+
height: inner_height = '93%',
|
84
|
+
width: inner_width = '100%',
|
85
|
+
unclickable = [],
|
86
|
+
symbolSize: _symbolSize = 'default',
|
87
|
+
color: inner_color = {
|
88
|
+
selected: 'red',
|
89
|
+
unselectable: 'grey',
|
90
|
+
},
|
91
|
+
singleclick = true,
|
92
|
+
} = props.config;
|
93
|
+
|
94
|
+
const [selected, setSelected] = useState({ nodes: [], category: null });
|
95
|
+
const { val = 'vnode' } = props;
|
96
|
+
|
97
|
+
const inner_style = {
|
98
|
+
border: debug ? '1px solid black' : 'none',
|
99
|
+
height: inner_height,
|
100
|
+
width: inner_width,
|
101
|
+
};
|
102
|
+
|
103
|
+
const maxValue = useMemo(() => {
|
104
|
+
const values = data.nodes.map(
|
105
|
+
(node) => parseFloat(node[_symbolSize]) || 50,
|
106
|
+
);
|
107
|
+
return Math.max(...values);
|
108
|
+
}, [data, _symbolSize]);
|
109
|
+
|
110
|
+
const processedData = useMemo(
|
111
|
+
() =>
|
112
|
+
processData(
|
113
|
+
data,
|
114
|
+
selected,
|
115
|
+
_symbolSize,
|
116
|
+
maxValue,
|
117
|
+
inner_color,
|
118
|
+
unclickable,
|
119
|
+
),
|
120
|
+
[data, selected, _symbolSize, maxValue, inner_color, unclickable],
|
121
|
+
);
|
122
|
+
|
123
|
+
const onChartClick = (params) => {
|
124
|
+
const category = params.data.category;
|
125
|
+
const name = params.data.name;
|
126
|
+
if (
|
127
|
+
params.dataType === 'node' &&
|
128
|
+
!unclickable.includes(category) &&
|
129
|
+
!unclickable.includes(name) &&
|
130
|
+
(selected.category === null || category === selected.category)
|
131
|
+
) {
|
132
|
+
let updatedSelectedNodes = [...selected.nodes];
|
133
|
+
let updatedSelectedCategory = selected.category;
|
134
|
+
if (selected.nodes.includes(name)) {
|
135
|
+
updatedSelectedNodes = updatedSelectedNodes.filter(
|
136
|
+
(nodeName) => nodeName !== name,
|
137
|
+
);
|
138
|
+
if (updatedSelectedNodes.length === 0) {
|
139
|
+
updatedSelectedCategory = null;
|
140
|
+
}
|
141
|
+
} else {
|
142
|
+
if (singleclick) updatedSelectedNodes = [name];
|
143
|
+
else updatedSelectedNodes.push(name);
|
144
|
+
updatedSelectedCategory = category;
|
145
|
+
}
|
146
|
+
setSelected({
|
147
|
+
nodes: updatedSelectedNodes,
|
148
|
+
category: updatedSelectedCategory,
|
149
|
+
});
|
150
|
+
}
|
151
|
+
};
|
152
|
+
|
153
|
+
const { setSharedData } = useAppContext();
|
154
|
+
|
155
|
+
useEffect(() => {
|
156
|
+
if (
|
157
|
+
val &&
|
158
|
+
Array.isArray(selected.nodes) &&
|
159
|
+
selected.nodes.length >= 0
|
160
|
+
) {
|
161
|
+
setSharedData((prevSharedData) => ({
|
162
|
+
...prevSharedData,
|
163
|
+
[val]: selected.nodes,
|
164
|
+
}));
|
165
|
+
}
|
166
|
+
}, [selected, val, setSharedData]);
|
167
|
+
|
168
|
+
return (
|
169
|
+
<div
|
170
|
+
key={id}
|
171
|
+
style={{ ...style, ..._style }}
|
172
|
+
className={className}>
|
173
|
+
{title && <h3>{title}</h3>}
|
174
|
+
<ReCharts
|
175
|
+
options={{
|
176
|
+
series: [
|
177
|
+
{
|
178
|
+
type: 'graph',
|
179
|
+
layout: 'force',
|
180
|
+
animation,
|
181
|
+
draggable,
|
182
|
+
label: {
|
183
|
+
position: 'top',
|
184
|
+
formatter: '{b}',
|
185
|
+
show: true,
|
186
|
+
},
|
187
|
+
data: processedData,
|
188
|
+
categories: data.categories,
|
189
|
+
edges: data.edges,
|
190
|
+
force: { repulsion, edgeLength },
|
191
|
+
},
|
192
|
+
],
|
193
|
+
}}
|
194
|
+
style={inner_style}
|
195
|
+
onEvents={{ click: onChartClick }}
|
196
|
+
/>
|
197
|
+
</div>
|
198
|
+
);
|
199
|
+
}
|
200
|
+
|
201
|
+
export default Macaron;
|
@@ -1,56 +1,56 @@
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
2
|
-
import axios from 'axios';
|
3
|
-
import { unified } from 'unified';
|
4
|
-
import remarkParse from 'remark-parse';
|
5
|
-
import remarkHtml from 'remark-html';
|
6
|
-
|
7
|
-
function Markdown({ props, style }) {
|
8
|
-
const { path } = props;
|
9
|
-
const [markdownContent, setMarkdownContent] = useState('');
|
10
|
-
const [error, setError] = useState(null);
|
11
|
-
|
12
|
-
useEffect(() => {
|
13
|
-
// Fetch the Markdown content from the specified path or file
|
14
|
-
axios.get(path).then(
|
15
|
-
(response) => {
|
16
|
-
const markdown = response.data;
|
17
|
-
|
18
|
-
// Create a new unified processor and use remark-parse and remark-html plugins
|
19
|
-
unified()
|
20
|
-
.use(remarkParse)
|
21
|
-
.use(remarkHtml)
|
22
|
-
.process(markdown, (err, file) => {
|
23
|
-
if (err) {
|
24
|
-
console.error('Error processing Markdown:', err);
|
25
|
-
setError('Error processing Markdown');
|
26
|
-
} else {
|
27
|
-
// Set the HTML content to be rendered
|
28
|
-
setMarkdownContent(String(file));
|
29
|
-
}
|
30
|
-
});
|
31
|
-
},
|
32
|
-
(error) => {
|
33
|
-
console.error('Error fetching Markdown:', error);
|
34
|
-
setError('Error fetching Markdown');
|
35
|
-
}
|
36
|
-
);
|
37
|
-
}, [path]);
|
38
|
-
|
39
|
-
if (error) {
|
40
|
-
return (
|
41
|
-
<div className='markdown-error' style={{ ...style }}>
|
42
|
-
{error}
|
43
|
-
</div>
|
44
|
-
);
|
45
|
-
}
|
46
|
-
|
47
|
-
return (
|
48
|
-
<div
|
49
|
-
className='markdown-content'
|
50
|
-
style={{ ...style }}
|
51
|
-
dangerouslySetInnerHTML={{ __html: markdownContent }}
|
52
|
-
/>
|
53
|
-
);
|
54
|
-
}
|
55
|
-
|
56
|
-
export default Markdown;
|
1
|
+
import React, { useEffect, useState } from 'react';
|
2
|
+
import axios from 'axios';
|
3
|
+
import { unified } from 'unified';
|
4
|
+
import remarkParse from 'remark-parse';
|
5
|
+
import remarkHtml from 'remark-html';
|
6
|
+
|
7
|
+
function Markdown({ props, style }) {
|
8
|
+
const { path } = props;
|
9
|
+
const [markdownContent, setMarkdownContent] = useState('');
|
10
|
+
const [error, setError] = useState(null);
|
11
|
+
|
12
|
+
useEffect(() => {
|
13
|
+
// Fetch the Markdown content from the specified path or file
|
14
|
+
axios.get(path).then(
|
15
|
+
(response) => {
|
16
|
+
const markdown = response.data;
|
17
|
+
|
18
|
+
// Create a new unified processor and use remark-parse and remark-html plugins
|
19
|
+
unified()
|
20
|
+
.use(remarkParse)
|
21
|
+
.use(remarkHtml)
|
22
|
+
.process(markdown, (err, file) => {
|
23
|
+
if (err) {
|
24
|
+
console.error('Error processing Markdown:', err);
|
25
|
+
setError('Error processing Markdown');
|
26
|
+
} else {
|
27
|
+
// Set the HTML content to be rendered
|
28
|
+
setMarkdownContent(String(file));
|
29
|
+
}
|
30
|
+
});
|
31
|
+
},
|
32
|
+
(error) => {
|
33
|
+
console.error('Error fetching Markdown:', error);
|
34
|
+
setError('Error fetching Markdown');
|
35
|
+
}
|
36
|
+
);
|
37
|
+
}, [path]);
|
38
|
+
|
39
|
+
if (error) {
|
40
|
+
return (
|
41
|
+
<div className='markdown-error' style={{ ...style }}>
|
42
|
+
{error}
|
43
|
+
</div>
|
44
|
+
);
|
45
|
+
}
|
46
|
+
|
47
|
+
return (
|
48
|
+
<div
|
49
|
+
className='markdown-content'
|
50
|
+
style={{ ...style }}
|
51
|
+
dangerouslySetInnerHTML={{ __html: markdownContent }}
|
52
|
+
/>
|
53
|
+
);
|
54
|
+
}
|
55
|
+
|
56
|
+
export default Markdown;
|