Skip to content

Commit 3dc8cf8

Browse files
authored
Merge pull request #56 from NeuroJSON/dev-fan
Bug fixes for pagination, tab persistence, and scroll behavior with UI enhancements
2 parents 2aaa1ec + c5ad42c commit 3dc8cf8

21 files changed

+756
-72
lines changed

public/img/logo_updated.png

27.3 KB
Loading

public/img/logo_yellow.png

27.5 KB
Loading
27.6 KB
Loading
-1.64 MB
Binary file not shown.
-1.01 MB
Binary file not shown.
-924 KB
Binary file not shown.

public/index.html

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@
5050
/> -->
5151

5252
<title>NeuroJSON.io - Free Data Worth Sharing</title>
53-
<link rel="stylesheet" href="https://leeoniya.github.io/uPlot/dist/uPlot.min.css" />
53+
<link
54+
rel="stylesheet"
55+
href="https://leeoniya.github.io/uPlot/dist/uPlot.min.css"
56+
/>
5457
<style>
5558
#chartpanel {
5659
background-color: #707070;
@@ -59,13 +62,13 @@
5962
margin-top: 20px;
6063
border-radius: 10px;
6164
}
62-
65+
6366
#chartpanel h4 {
6467
padding-top: 0;
6568
margin-bottom: 10px;
6669
color: black;
6770
}
68-
71+
6972
#chartpanel a.closebtn {
7073
float: right;
7174
font-size: 28px;
@@ -74,13 +77,12 @@
7477
text-decoration: none;
7578
margin-top: -10px;
7679
}
77-
80+
7881
.uplot {
7982
margin: auto;
8083
max-width: 100%;
8184
}
8285
</style>
83-
8486
</head>
8587
<body>
8688
<noscript>You need to enable JavaScript to run this app.</noscript>
@@ -107,7 +109,23 @@
107109
<script src="%PUBLIC_URL%/js/jdata.js"></script>
108110
<script src="%PUBLIC_URL%/js/bjdata.js"></script>
109111
<script src="https://bundle.run/[email protected]"></script>
110-
<script>var buffer_module = buffer;</script>
112+
<script>
113+
var buffer_module = buffer;
114+
</script>
111115
<script src="https://leeoniya.github.io/uPlot/dist/uPlot.iife.min.js"></script>
116+
<!-- Google tag (gtag.js) -->
117+
<script
118+
async
119+
src="https://www.googletagmanager.com/gtag/js?id=G-F0BKEF4Y2R"
120+
></script>
121+
<script>
122+
window.dataLayer = window.dataLayer || [];
123+
function gtag() {
124+
dataLayer.push(arguments);
125+
}
126+
gtag("js", new Date());
127+
128+
gtag("config", "G-F0BKEF4Y2R");
129+
</script>
112130
</body>
113131
</html>

src/App.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { GlobalStyles } from "@mui/material";
12
import { ThemeProvider } from "@mui/material/styles";
23
import Routes from "components/Routes";
34
import theme from "design/theme";
@@ -6,6 +7,13 @@ import { BrowserRouter } from "react-router-dom";
67
const App = () => {
78
return (
89
<ThemeProvider theme={theme}>
10+
<GlobalStyles
11+
styles={{
12+
body: {
13+
overscrollBehavior: "none",
14+
},
15+
}}
16+
/>
917
<BrowserRouter basename={process.env.PUBLIC_URL}>
1018
<Routes />
1119
</BrowserRouter>
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
import { Tabs, Tab, Box, Typography } from "@mui/material";
2+
import { Colors } from "design/theme";
3+
import React from "react";
4+
import { useState } from "react";
5+
6+
interface LoadDatasetTabsProps {
7+
pagename: string;
8+
docname: string;
9+
dbname: string;
10+
serverUrl: string;
11+
datasetDocument?: any;
12+
onekey: string;
13+
}
14+
15+
const flashcardStyles = {
16+
container: {
17+
display: "flex",
18+
flexWrap: "wrap",
19+
justifyContent: "space-between",
20+
marginTop: "20px",
21+
gap: "0px",
22+
},
23+
flashcard: {
24+
background: "white",
25+
padding: "15px",
26+
marginBottom: "0px",
27+
borderRadius: "8px",
28+
borderLeft: `5px solid ${Colors.green}`,
29+
width: "100%",
30+
boxSizing: "border-box" as const,
31+
},
32+
flashcardTitle: {
33+
marginTop: 0,
34+
marginBottom: 8,
35+
fontWeight: "bold",
36+
color: Colors.darkPurple,
37+
},
38+
codeBlock: {
39+
display: "block",
40+
background: "#e0e0e0",
41+
color: Colors.black,
42+
padding: "10px",
43+
borderRadius: "5px",
44+
whiteSpace: "pre-wrap",
45+
},
46+
};
47+
48+
const LoadDatasetTabs: React.FC<LoadDatasetTabsProps> = ({
49+
pagename,
50+
docname,
51+
dbname,
52+
serverUrl,
53+
datasetDocument,
54+
onekey,
55+
}) => {
56+
const [tabIndex, setTabIndex] = useState(0);
57+
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
58+
setTabIndex(newValue);
59+
};
60+
const datasetDesc = datasetDocument?.["dataset_description.json"];
61+
const datasetName = datasetDesc?.Name?.includes(" - ")
62+
? datasetDesc.Name.split(" - ")[1]
63+
: datasetDesc?.Name || datasetDocument?._id || docname;
64+
const datasetUrl = datasetName
65+
? `${serverUrl}${dbname}/${encodeURIComponent(datasetName)}/`
66+
: `${serverUrl}${dbname}/`;
67+
68+
const TabPanel = ({
69+
children,
70+
value,
71+
index,
72+
}: {
73+
children?: React.ReactNode;
74+
value: number;
75+
index: number;
76+
}) => {
77+
return (
78+
<div role="tabpanel" hidden={value !== index}>
79+
{value === index && <Box sx={{ p: 2 }}>{children}</Box>}
80+
</div>
81+
);
82+
};
83+
84+
return (
85+
<>
86+
<Tabs
87+
value={tabIndex}
88+
onChange={handleTabChange}
89+
variant="scrollable"
90+
scrollButtons="auto"
91+
sx={{
92+
"& .MuiTab-root": {
93+
color: Colors.lightGray, // default color
94+
fontSize: "large",
95+
textTransform: "none",
96+
},
97+
"& .MuiTab-root.Mui-selected": {
98+
color: Colors.green, // active tab color
99+
fontWeight: "bold",
100+
},
101+
"& .MuiTabs-indicator": {
102+
backgroundColor: Colors.green,
103+
},
104+
}}
105+
>
106+
<Tab label="Python (REST API)" />
107+
<Tab label="MATLAB (REST API)" />
108+
<Tab label="MATLAB/Octave (Local)" />
109+
<Tab label="Python (Local)" />
110+
<Tab label="C++" />
111+
<Tab label="Node.js" />
112+
</Tabs>
113+
114+
{/* FLASHCARD 1: Python REST API */}
115+
<TabPanel value={tabIndex} index={0}>
116+
<Box style={flashcardStyles.flashcard}>
117+
<Typography variant="h6" style={flashcardStyles.flashcardTitle}>
118+
Load by URL with REST-API in Python
119+
</Typography>
120+
<Typography>Install:</Typography>
121+
<code style={flashcardStyles.codeBlock}>
122+
pip install jdata bjdata numpy
123+
</code>
124+
<Typography>Load from URL:</Typography>
125+
<code style={flashcardStyles.codeBlock}>
126+
{`import jdata as jd
127+
data = jd.loadurl('${datasetUrl}')
128+
129+
# List all externally linked files
130+
links = jd.jsonpath(data, '$.._DataLink_')
131+
132+
# Download & cache anatomical nii.gz data for sub-01/sub-02
133+
jd.jdlink(links, {'regex': 'anat/sub-0[12]_.*\\.nii'})`}
134+
</code>
135+
</Box>
136+
</TabPanel>
137+
138+
{/* FLASHCARD 2: MATLAB REST API */}
139+
<TabPanel value={tabIndex} index={1}>
140+
<Box style={flashcardStyles.flashcard}>
141+
<Typography variant="h6" style={flashcardStyles.flashcardTitle}>
142+
Load by URL with REST-API in MATLAB
143+
</Typography>
144+
<Typography>Install:</Typography>
145+
<code style={flashcardStyles.codeBlock}>
146+
Download and addpath to JSONLab
147+
</code>
148+
<Typography>Load from URL:</Typography>
149+
<code style={flashcardStyles.codeBlock}>
150+
{`data = loadjson('${datasetUrl}');
151+
152+
% or without JSONLab (webread cannot decode JData annotations)
153+
data = webread('${datasetUrl}');
154+
155+
% List all externally linked files
156+
links = jsonpath(data, '$.._DataLink_');
157+
158+
% Download & cache anatomical nii.gz data for sub-01/sub-02
159+
niidata = jdlink(links, 'regex', 'anat/sub-0[12]_.*\\.nii');`}
160+
</code>
161+
</Box>
162+
</TabPanel>
163+
164+
{/* FLASHCARD 3: MATLAB/Octave */}
165+
<TabPanel value={tabIndex} index={2}>
166+
<Box style={flashcardStyles.flashcard}>
167+
<Typography variant="h6" style={flashcardStyles.flashcardTitle}>
168+
Use in MATLAB/Octave
169+
</Typography>
170+
<Typography>Load:</Typography>
171+
<code
172+
style={flashcardStyles.codeBlock}
173+
>{`data = loadjd('${docname}.json');`}</code>
174+
<Typography>Read value:</Typography>
175+
<code
176+
style={flashcardStyles.codeBlock}
177+
>{`data.(encodevarname('${onekey}'))`}</code>
178+
</Box>
179+
</TabPanel>
180+
181+
{/* FLASHCARD 4: Python Local */}
182+
<TabPanel value={tabIndex} index={3}>
183+
<Box style={flashcardStyles.flashcard}>
184+
<Typography variant="h6" style={flashcardStyles.flashcardTitle}>
185+
Use in Python
186+
</Typography>
187+
<Typography>Load:</Typography>
188+
<code style={flashcardStyles.codeBlock}>
189+
{`import jdata as jd
190+
data = jd.load('${docname}.json')`}
191+
</code>
192+
<Typography>Read value:</Typography>
193+
<code style={flashcardStyles.codeBlock}>{`data["${onekey}"]`}</code>
194+
</Box>
195+
</TabPanel>
196+
197+
{/* FLASHCARD 5: C++ */}
198+
<TabPanel value={tabIndex} index={4}>
199+
<Box style={flashcardStyles.flashcard}>
200+
<Typography variant="h6" style={flashcardStyles.flashcardTitle}>
201+
Use in C++
202+
</Typography>
203+
<Typography>Install:</Typography>
204+
<code style={flashcardStyles.codeBlock}>
205+
Download JSON for Modern C++ json.hpp
206+
</code>
207+
<Typography>Load:</Typography>
208+
<code style={flashcardStyles.codeBlock}>
209+
{`#include "json.hpp"
210+
using json=nlohmann::ordered_json;
211+
212+
std::ifstream datafile("${docname}.json");
213+
json data(datafile);`}
214+
</code>
215+
<Typography>Read value:</Typography>
216+
<code
217+
style={flashcardStyles.codeBlock}
218+
>{`std::cout << data["${onekey}"];`}</code>
219+
</Box>
220+
</TabPanel>
221+
222+
{/* FLASHCARD 6: Node.js */}
223+
<TabPanel value={tabIndex} index={5}>
224+
<Box style={flashcardStyles.flashcard}>
225+
<Typography variant="h6" style={flashcardStyles.flashcardTitle}>
226+
Use in JS/Node.js
227+
</Typography>
228+
<Typography>Install:</Typography>
229+
<code style={flashcardStyles.codeBlock}>
230+
npm install jda numjs pako atob
231+
</code>
232+
<Typography>Load:</Typography>
233+
<code style={flashcardStyles.codeBlock}>
234+
{`const fs = require("fs");
235+
const jd = require("jda");
236+
global.atob = require("atob");
237+
238+
const fn = "${docname}.json";
239+
var jstr = fs.readFileSync(fn).toString().replace(/\\n/g, "");
240+
var data = new jd(JSON.parse(jstr));
241+
data = data.decode();`}
242+
</code>
243+
<Typography>Read value:</Typography>
244+
<code
245+
style={flashcardStyles.codeBlock}
246+
>{`console.log(data.data["${onekey}"]);`}</code>
247+
</Box>
248+
</TabPanel>
249+
</>
250+
);
251+
};
252+
253+
export default LoadDatasetTabs;

0 commit comments

Comments
 (0)