-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathindex.tsx
141 lines (123 loc) · 5.5 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import React from 'react'
import { MetaNode } from '@/spec/metanode'
import { z } from 'zod'
import { FileDesURLC } from '../MetENP_on_MetSet'
import { additional_info_icon, drug_icon } from '@/icons';
const MetGeneMetObjC = z.object({
Gene: z.string(),
KEGG_COMPOUND_ID: z.string(),
REFMET_NAME: z.string(),
KEGG_REACTION_ID: z.string(),
METSTAT_LINK: z.string(),
});
export type MetGeneMetObj = z.infer<typeof MetGeneMetObjC>
// important ref: https://rsinohara.github.io/json-to-zod-react/
// array of objects: [{}]
export const MetGeneMetObjArrayC = z.array(
MetGeneMetObjC
)
export type MetGeneMetObjArray = z.infer<typeof MetGeneMetObjArrayC>
// array of array of objects: [[{}]]
export const MetGeneMetObjArray2C = z.array(
MetGeneMetObjArrayC
)
export type MetGeneMetObjArray2 = z.infer<typeof MetGeneMetObjArray2C>
// Mano: 2023/08/01: To allow getting just the file URL (the file will have the actual 2D-array json content)
// Schema for output from application of MetENP on a list of metabolites (MetaboliteSet)
export const MGMetTableInfoC = z.object({
jsonfile: FileDesURLC,
contents: MetGeneMetObjArray2C
})
export type MGMetTableInfo = z.infer<typeof MGMetTableInfoC>
// A unique name for your data type is used here
export const MetgeneMetaboliteTable = MetaNode('MetgeneMetaboliteTable')
// Human readble descriptors about this node should go here
.meta({
label: 'MetGENE metabolite table',
description: 'MetGENE metabolite table',
icon: [drug_icon, additional_info_icon],
external: true,
})
// this should have a codec which can encode or decode the data type represented by this node
// using zod, a compile-time and runtime type-safe codec can be constructed
//.codec(MetGeneMetObjArray2C) // Mano: 2023/08/03: Original
.codec(MGMetTableInfoC)
// react component rendering your data goes here
.view(data => {
const heading1 = "Gene"
const heading2 = "KEGG_COMPOUND_ID"
const heading3 = "REFMET_NAME"
const heading4 = "KEGG_REACTION_ID"
const heading5 = "METSTAT_LINK"
const MaxRows2Show = 50;
const contents = data.contents.filter(arrval => arrval.length > 0)
if (contents.length === 0) {
return (
<div className="prose max-w-none">
<h2 className="m-0">MetGENE Metabolites</h2>
<span className="text-red-500">No metabolites found.</span>
</div>
)
}
const ng = contents.length;
const arrlen:number[] = contents.map(x=>x.length);
let arrlen_cumsum: number[] = [];
arrlen.reduce( (prev, curr,i) => arrlen_cumsum[i] = prev + curr , 0 );
//console.log(arrlen); console.log(arrlen_cumsum);
//window.alert(arrlen); window.alert(arrlen_cumsum);
let isLessThanMax = (x: number) => x < MaxRows2Show;
//didn't work: let ng2show = arrlen_cumsum.findLastIndex(isLessThanMax); if(ng2show < 0) ng2show = 0; // Math.min(MaxRows2Show, ng);
let ng2show = 0; for(let ii = 0; ii < arrlen_cumsum.length; ii++){ ng2show = ii; if(arrlen_cumsum[ii] > MaxRows2Show) {break;}}
// Show up to the point, total numrows so far is about less than MaxRows2Show, OK to show it for next gene but no more
ng2show = ng2show + 1; // actual number rather than index
let ExtraText_if_more_rows = "";
if(ng2show < ng) ExtraText_if_more_rows = ` The tables for the first ${ng2show} genes are shown below.`;
// Below, data.contents is array of array of objects; trying to show at most 50 rows
return (
<div className="prose max-w-none">
<h2 className="m-0">MetGENE Metabolites</h2>
<span style={{ color: "#0000F0" }}>
<h3>Full table as a json file is available at <a href={`${data.jsonfile.FileURL}`} target="_blank">{data.jsonfile.FileDescription}</a>. {ExtraText_if_more_rows}</h3>
</span>
{contents.slice(0, ng2show).map((arrayVal:MetGeneMetObjArray, index:number) => (
arrayVal.length > 0 && <div key={index}>
<table>
<thead>
<tr>
<th>{heading1}</th>
<th>{heading2}</th>
<th>{heading3}</th>
<th>{heading4}</th>
<th>{heading5}</th>
</tr>
</thead>
<tbody>
{arrayVal.map((val:MetGeneMetObj, j:number) => {
const all_rxn_ids = val.KEGG_REACTION_ID
const cpd_id = val.KEGG_COMPOUND_ID
const rxn_id_arr = all_rxn_ids.split(", ")
return (
<tr key={j}>
<td>{val.Gene}</td>
<td><a href = {`https://www.kegg.jp/entry/${val.KEGG_COMPOUND_ID}`} target = "_blank">{val.KEGG_COMPOUND_ID}</a></td>
<td><a href = {`https://www.metabolomicsworkbench.org/databases/refmet/refmet_details.php?REFMET_NAME=${val.REFMET_NAME}`} target = "_blank">{val.REFMET_NAME}</a></td>
<td>
{rxn_id_arr.map((rxn_id:string, i:number) =>
<>
{i > 0 ? <span>, </span> : null}
<a key={i} href = {`https://www.genome.jp/entry/rn:${rxn_id}`} target = "_blank">{rxn_id}</a>
</>
)}
</td>
<td><a href = {val.METSTAT_LINK} target = "_blank">METSTAT</a></td>
</tr>
)
})}
</tbody>
</table>
</div>
))}
</div>
)
})
.build()