gramene-search 1.6.46 → 1.7.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.
@@ -12,12 +12,27 @@ const metaRenderer = params => {
12
12
  }
13
13
  const sampleRenderer = params => {
14
14
  const sampleMeta = params.value;
15
- return JSON.stringify(sampleMeta,null,2);
15
+ return (
16
+ <label>
17
+ <input
18
+ type="checkbox"
19
+ checked={params.desiredSamples.hasOwnProperty(sampleMeta._id)}
20
+ onChange={() => params.doToggleExpressionSample(sampleMeta._id)}
21
+ />
22
+ &nbsp;{sampleMeta.experiment}-{sampleMeta.group}
23
+ </label>
24
+ );
25
+ // return JSON.stringify(sampleMeta,null,2);
16
26
  }
27
+ const connectedSampleRenderer = connect(
28
+ 'selectDesiredSamples', // current set of samples to fetch expression data for
29
+ 'doToggleExpressionSample',
30
+ sampleRenderer
31
+ );
17
32
  const Study = props => {
18
33
  let samples = props.expressionSamples[props.id];
19
34
  let sampleMetadata = [];
20
- let metadataFields = [{ field: "sampleId", cellRenderer: sampleRenderer }];
35
+ let metadataFields = [{ field: "sampleId", cellRenderer: connectedSampleRenderer }];
21
36
  let isFactor={};
22
37
  samples.forEach((sample, idx) => {
23
38
  if (idx === 0) {
@@ -76,5 +91,4 @@ const Study = props => {
76
91
  };
77
92
  export default connect(
78
93
  'selectExpressionSamples',
79
- 'doToggleExpressionSample',
80
94
  Study);
@@ -8,7 +8,8 @@ class TaxDist extends React.Component {
8
8
  constructor(props) {
9
9
  super(props);
10
10
  this.state = {
11
- collapseEmpties: true
11
+ collapseEmpties: true,
12
+ comparaOnly: true
12
13
  };
13
14
  }
14
15
  handleSelection(selections) {
@@ -23,6 +24,9 @@ class TaxDist extends React.Component {
23
24
  toggleEmpties() {
24
25
  this.setState({collapseEmpties: !this.state.collapseEmpties})
25
26
  }
27
+ toggleCompara() {
28
+ this.setState({comparaOnly: !this.state.comparaOnly})
29
+ }
26
30
  render() {
27
31
  let selectedTaxa = {};
28
32
  if (this.props.grameneSearch && this.state.collapseEmpties) {
@@ -31,15 +35,34 @@ class TaxDist extends React.Component {
31
35
  })
32
36
  }
33
37
  else {
34
- selectedTaxa = this.props.grameneGenomes.active
38
+ if (Object.keys(this.props.grameneGenomes.active).length === 0 && this.props.grameneMaps) {
39
+ Object.keys(this.props.grameneMaps).forEach(tid => selectedTaxa[tid] = true);
40
+ }
41
+ else {
42
+ selectedTaxa = this.props.grameneGenomes.active
43
+ }
44
+ }
45
+ if (this.state.comparaOnly && this.props.grameneMaps) {
46
+ Object.keys(selectedTaxa).forEach(tid => {
47
+ if (!this.props.grameneMaps[tid].in_compara) {
48
+ delete selectedTaxa[tid];
49
+ }
50
+ })
35
51
  }
36
52
  return (
37
53
  <div className="results-vis big-vis">
38
- {this.props.grameneTaxDist && <button type="button"
39
- className="btn btn-primary btn-sm"
40
- onClick={this.toggleEmpties.bind(this)}>
54
+ {this.props.grameneTaxDist && <span>
55
+ <button type="button"
56
+ className="btn btn-outline-primary btn-sm"
57
+ onClick={this.toggleEmpties.bind(this)}>
41
58
  {this.state.collapseEmpties ? 'Expand' : 'Collapse'} empty branches
42
- </button>}
59
+ </button>
60
+ <button type="button"
61
+ className="btn btn-outline-success btn-sm"
62
+ onClick={this.toggleCompara.bind(this)}>
63
+ Show {this.state.comparaOnly ? 'all genomes' : 'compara only'}
64
+ </button>
65
+ </span>}
43
66
  {this.props.grameneTaxDist && <Vis taxonomy={this.props.grameneTaxDist}
44
67
  selectedTaxa={selectedTaxa}
45
68
  onSelection={this.handleSelection.bind(this)}
@@ -63,5 +86,6 @@ export default connect(
63
86
  'selectGrameneTaxDist',
64
87
  'selectGrameneGenomes',
65
88
  'selectGrameneSearch',
89
+ 'selectGrameneMaps',
66
90
  TaxDist
67
91
  );
@@ -55,6 +55,32 @@ const GeneListDisplayComponent = props => {
55
55
  }
56
56
  };
57
57
 
58
+ // Example functions for viewing and deleting lists
59
+ const viewGeneList = (list) => {
60
+ alert(`Viewing gene list: ${list.label}`);
61
+ props.addFilter({
62
+ category: 'Gene List',
63
+ fq_field: 'saved_search',
64
+ fq_value: list.hash,
65
+ name: list.label
66
+ })
67
+ };
68
+
69
+ const deleteGeneList = async (api,listId) => {
70
+ if (window.confirm('Are you sure you want to delete this gene list?')) {
71
+ // Replace with the actual delete request
72
+ try {
73
+ await fetch(`${api}/gene_lists/${listId}`, {
74
+ method: 'DELETE',
75
+ });
76
+ alert('Gene list deleted!');
77
+ // Optionally refetch the updated list
78
+ } catch (err) {
79
+ alert('Failed to delete gene list.');
80
+ }
81
+ }
82
+ };
83
+
58
84
  // Fetch data when the component is mounted
59
85
  useEffect(() => {
60
86
  fetchPublicGeneLists();
@@ -76,6 +102,7 @@ const GeneListDisplayComponent = props => {
76
102
  {privateGeneLists.length > 0 && (
77
103
  <Table striped bordered hover className="mt-4">
78
104
  <thead>
105
+ <tr><th colspan={3}>My gene lists</th></tr>
79
106
  <tr>
80
107
  <th>List Name</th>
81
108
  <th>Number of Genes</th>
@@ -86,7 +113,7 @@ const GeneListDisplayComponent = props => {
86
113
  {privateGeneLists.map((list, index) => (
87
114
  <tr key={index}>
88
115
  <td>{list.label}</td>
89
- <td>{list.hash}</td>
116
+ <td>{list.n_genes || 0}</td>
90
117
  <td>
91
118
  <Button variant="info" onClick={() => viewGeneList(list)}>
92
119
  View
@@ -104,6 +131,9 @@ const GeneListDisplayComponent = props => {
104
131
  {publicGeneLists.length > 0 ? (
105
132
  <Table striped bordered hover className="mt-4">
106
133
  <thead>
134
+ <tr>
135
+ <th colSpan={3}>Public gene lists</th>
136
+ </tr>
107
137
  <tr>
108
138
  <th>List Name</th>
109
139
  <th>Number of Genes</th>
@@ -114,7 +144,7 @@ const GeneListDisplayComponent = props => {
114
144
  {publicGeneLists.map((list, index) => (
115
145
  <tr key={index}>
116
146
  <td>{list.label}</td>
117
- <td>{list.hash}</td>
147
+ <td>{list.n_genes || 0}</td>
118
148
  <td>
119
149
  <Button variant="info" onClick={() => viewGeneList(list)}>
120
150
  View
@@ -136,27 +166,6 @@ const GeneListDisplayComponent = props => {
136
166
  );
137
167
  };
138
168
 
139
- // Example functions for viewing and deleting lists
140
- const viewGeneList = (list) => {
141
- alert(`Viewing gene list: ${list.name}\nGenes: ${list.genes.join(', ')}`);
142
- };
143
-
144
- const deleteGeneList = async (api,listId) => {
145
- if (window.confirm('Are you sure you want to delete this gene list?')) {
146
- // Replace with the actual delete request
147
- try {
148
- await fetch(`${api}/gene_lists/${listId}`, {
149
- method: 'DELETE',
150
- });
151
- alert('Gene list deleted!');
152
- // Optionally refetch the updated list
153
- } catch (err) {
154
- alert('Failed to delete gene list.');
155
- }
156
- }
157
- };
158
-
159
-
160
169
  const GeneListComponent = props => {
161
170
  const [geneList, setGeneList] = useState('');
162
171
  const [listHash, setListHash] = useState(null);
@@ -230,6 +239,7 @@ const GeneListComponent = props => {
230
239
  label: listName,
231
240
  hash: listHash,
232
241
  site: props.site,
242
+ n_genes: validatedList.length,
233
243
  isPublic: listIsPublic
234
244
  };
235
245
  const queryString = new URLSearchParams(queryParams).toString();
@@ -348,7 +358,7 @@ const UserGeneListsComponent = props => {
348
358
  <Container fluid>
349
359
  <Row>
350
360
  <Col><GeneListComponent api={props.configuration.grameneData} site={props.configuration.id}/></Col>
351
- <Col><GeneListDisplayComponent api={props.configuration.grameneData} site={props.configuration.id}/></Col>
361
+ <Col><GeneListDisplayComponent api={props.configuration.grameneData} site={props.configuration.id} addFilter={props.doAcceptGrameneSuggestion}/></Col>
352
362
  </Row>
353
363
  </Container>
354
364
  )
@@ -356,5 +366,6 @@ const UserGeneListsComponent = props => {
356
366
 
357
367
  export default connect(
358
368
  'selectConfiguration',
369
+ 'doAcceptGrameneSuggestion',
359
370
  UserGeneListsComponent
360
371
  );
@@ -34,6 +34,7 @@ const Detail = props => {
34
34
  const gene = props.geneDocs[props.searchResult.id];
35
35
  const [atlasExperiment, setAtlasExperiment] = useState(null);
36
36
  const [atlasExperimentList, setAtlasExperimentList] = useState([]);
37
+ const [atlasFacets, setAtlasFacets] = useState(null);
37
38
  const [isLocal, setIsLocal] = useState(false);
38
39
  const [activeTab, setActiveTab] = useState('gene');
39
40
 
@@ -43,6 +44,7 @@ const Detail = props => {
43
44
  useEffect(() => {
44
45
  const tid = Math.floor(gene.taxon_id / 1000);
45
46
  if (props.expressionStudies[tid]) {
47
+ let facets={Differential: {}, Baseline: {}};
46
48
  let eList = props.expressionStudies[tid].sort((a,b) => {
47
49
  const a_name = `${a.type}:${a.description || a._id}`;
48
50
  const b_name = `${b.type}:${b.description || b._id}`;
@@ -52,8 +54,9 @@ const Detail = props => {
52
54
  const in_gxa = new Set(props.searchResult.expressed_in_gxa_attr_ss);
53
55
  eList = eList.filter(e => in_gxa.has(e._id))
54
56
  }
57
+ eList.forEach(e => {e.factors.forEach(factor => facets[e.type][factor] = 1);});
55
58
  setAtlasExperimentList(eList);
56
-
59
+ setAtlasFacets(facets);
57
60
  let refExp = eList.filter(e => e.isRef);
58
61
  if (refExp.length === 1) {
59
62
  setAtlasExperiment(refExp[0]._id);
@@ -69,13 +72,13 @@ const Detail = props => {
69
72
  let paralogs = [];
70
73
  if (props.grameneParalogs && props.grameneParalogs[gene._id]) {
71
74
  paralogs = props.grameneParalogs[gene._id];
72
- } else if(gene.homology) {
75
+ } else if (gene.homology) {
73
76
  props.doRequestParalogs(gene._id, gene.homology.supertree, gene.taxon_id);
74
77
  }
75
78
  // if (gene.homology && gene.homology.homologous_genes && gene.homology.homologous_genes.within_species_paralog) {
76
79
  // paralogs = gene.homology.homologous_genes.within_species_paralog;
77
80
  // }
78
- if (paralogs.length > 1 && atlasExperiment) {
81
+ if (paralogs.length > 0 && atlasExperiment) {
79
82
  paralogs_url= `https://dev.gramene.org/static/atlasWidget.html?genes=${paralogs.join(' ')}&experiment=${atlasExperiment}&localAPI=${isLocal}`;
80
83
  }
81
84
  return <Tabs activeKey={activeTab} onSelect={(k) => setActiveTab(k)}>
package/src/demo.js CHANGED
@@ -138,9 +138,9 @@ const panSites = [
138
138
  ensemblURL: 'https://ensembl-dev.sorghumbase.org',
139
139
  ensemblSite: 'https://ensembl-dev.sorghumbase.org',
140
140
  ensemblRest: 'https://data.gramene.org/pansite-ensembl-108',
141
- grameneData: 'https://data.sorghumbase.org/auth_testing',
141
+ grameneData: 'https://data.sorghumbase.org/sorghum_v10',
142
142
  ga: 'G-L5KXDCCZ16',
143
- targetTaxonId: 4558003,
143
+ targetTaxonId: 4558001,
144
144
  alertText: 'Click the search icon in the menu bar or type /',
145
145
  showViews: true,
146
146
  details: {
package/src/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <title>Gramene Search</title>
6
6
  <script>
7
7
  window.gramene = {};
8
- gramene.defaultServer = 'https://data.gramene.org/v68/swagger';
8
+ gramene.defaultServer = 'https://data.gramene.org/v69/swagger';
9
9
  </script>
10
10
  <script async src="./static/gramene-dalliance/dalliance-all.js"></script>
11
11
  <script async src="https://plantreactome.gramene.org/DiagramJs/diagram/diagram.nocache.js"></script>
@@ -38,4 +38,4 @@
38
38
  }
39
39
  </script>
40
40
  </body>
41
- </html>
41
+ </html>
package/src/rice.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <title>Gramene Search</title>
6
6
  <script>
7
7
  window.gramene = {};
8
- gramene.defaultServer = 'https://data.gramene.org/oryza_v8/swagger';
8
+ gramene.defaultServer = 'https://data.gramene.org/oryza_v9/swagger';
9
9
  </script>
10
10
  <script async src="./static/gramene-dalliance/dalliance-all.js"></script>
11
11
  <script async src="https://plantreactome.gramene.org/DiagramJs/diagram/diagram.nocache.js"></script>
package/src/sorghum.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <title>Gramene Search</title>
6
6
  <script>
7
7
  window.gramene = {};
8
- gramene.defaultServer = 'https://data.sorghumbase.org/sorghum_v9/swagger';
8
+ gramene.defaultServer = 'https://data.sorghumbase.org/sorghum_v10/swagger';
9
9
  </script>
10
10
  <script async src="./static/gramene-dalliance/dalliance-all.js"></script>
11
11
  <script async src="https://plantreactome.gramene.org/DiagramJs/diagram/diagram.nocache.js"></script>
@@ -1,137 +0,0 @@
1
- var $eTR7Q$reactjsxruntime = require("react/jsx-runtime");
2
- var $eTR7Q$react = require("react");
3
- var $eTR7Q$reduxbundlerreact = require("redux-bundler-react");
4
- var $eTR7Q$aggridreact = require("ag-grid-react");
5
- require("ag-grid-community/styles/ag-grid.css");
6
- require("ag-grid-community/styles/ag-theme-quartz.css");
7
-
8
-
9
- function $parcel$defineInteropFlag(a) {
10
- Object.defineProperty(a, '__esModule', {value: true, configurable: true});
11
- }
12
-
13
- function $parcel$export(e, n, v, s) {
14
- Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
15
- }
16
-
17
- var $parcel$global = globalThis;
18
- var parcelRequire = $parcel$global["parcelRequire94c2"];
19
- var parcelRegister = parcelRequire.register;
20
- parcelRegister("7zuJ6", function(module, exports) {
21
-
22
- $parcel$defineInteropFlag(module.exports);
23
-
24
- $parcel$export(module.exports, "default", () => $5833a2eeefc77457$export$2e2bcd8739ae039);
25
-
26
-
27
-
28
-
29
-
30
-
31
- const $5833a2eeefc77457$var$metaRenderer = (params)=>{
32
- if (params.value.ontology) return /*#__PURE__*/ (0, $eTR7Q$reactjsxruntime.jsx)("a", {
33
- href: `http://purl.obolibrary.org/obo/${params.value.id.replace(":", "_")}`,
34
- target: "_blank",
35
- children: params.value.label
36
- });
37
- return params.value.label;
38
- };
39
- const $5833a2eeefc77457$var$sampleRenderer = (params)=>{
40
- const sampleMeta = params.value;
41
- return JSON.stringify(sampleMeta, null, 2);
42
- };
43
- const $5833a2eeefc77457$var$Study = (props)=>{
44
- let samples = props.expressionSamples[props.id];
45
- let sampleMetadata = [];
46
- let metadataFields = [
47
- {
48
- field: "sampleId",
49
- cellRenderer: $5833a2eeefc77457$var$sampleRenderer
50
- }
51
- ];
52
- let isFactor = {};
53
- samples.forEach((sample, idx)=>{
54
- if (idx === 0) {
55
- let factors = {
56
- headerName: 'Experimental Variables',
57
- children: []
58
- };
59
- sample.factor.forEach((factor)=>{
60
- factors.children.push({
61
- field: factor.type,
62
- cellRenderer: $5833a2eeefc77457$var$metaRenderer
63
- });
64
- isFactor[factor.type] = true;
65
- });
66
- metadataFields.push(factors);
67
- let characteristics = {
68
- headerName: 'Sample Characteristics',
69
- children: []
70
- };
71
- sample.characteristic.forEach((ch)=>{
72
- if (!isFactor[ch.type]) characteristics.children.push({
73
- field: ch.type,
74
- cellRenderer: $5833a2eeefc77457$var$metaRenderer
75
- });
76
- });
77
- metadataFields.push(characteristics);
78
- }
79
- let s_info = {
80
- sampleId: sample
81
- };
82
- sample.factor.forEach((factor)=>{
83
- s_info[factor.type] = {
84
- label: factor.label
85
- };
86
- if (factor.ontology) {
87
- s_info[factor.type]['ontology'] = factor.ontology;
88
- s_info[factor.type]['id'] = factor.id;
89
- }
90
- });
91
- sample.characteristic.forEach((ch)=>{
92
- s_info[ch.type] = {
93
- label: ch.label
94
- };
95
- if (ch.ontology) {
96
- s_info[ch.type]['ontology'] = ch.ontology;
97
- s_info[ch.type]['id'] = ch.id;
98
- }
99
- });
100
- sampleMetadata.push(s_info);
101
- });
102
- const [rowData, setRowData] = (0, $eTR7Q$react.useState)(sampleMetadata);
103
- const [colDefs, setColDefs] = (0, $eTR7Q$react.useState)(metadataFields);
104
- const defaultColDef = (0, $eTR7Q$react.useMemo)(()=>{
105
- return {
106
- filter: true
107
- };
108
- }, []);
109
- return /*#__PURE__*/ (0, $eTR7Q$reactjsxruntime.jsxs)("div", {
110
- children: [
111
- /*#__PURE__*/ (0, $eTR7Q$reactjsxruntime.jsx)("div", {
112
- className: "ag-theme-quartz",
113
- style: {
114
- height: `${44 * (samples.length + 2)}px`
115
- },
116
- children: /*#__PURE__*/ (0, $eTR7Q$reactjsxruntime.jsx)((0, $eTR7Q$aggridreact.AgGridReact), {
117
- rowData: rowData,
118
- columnDefs: colDefs,
119
- defaultColDef: defaultColDef
120
- })
121
- }),
122
- /*#__PURE__*/ (0, $eTR7Q$reactjsxruntime.jsxs)("a", {
123
- href: `https://www.ebi.ac.uk/gxa/experiments/${props.id}`,
124
- children: [
125
- "EBI Atlas Experiment: ",
126
- props.id
127
- ]
128
- })
129
- ]
130
- });
131
- };
132
- var $5833a2eeefc77457$export$2e2bcd8739ae039 = (0, $eTR7Q$reduxbundlerreact.connect)('selectExpressionSamples', 'doToggleExpressionSample', $5833a2eeefc77457$var$Study);
133
-
134
- });
135
-
136
-
137
- //# sourceMappingURL=Study.826d318c.js.map
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/results/Study.js"],"sourcesContent":["import React, { useState, useMemo } from 'react'\nimport {connect} from \"redux-bundler-react\";\nimport { AgGridReact } from \"ag-grid-react\";\nimport \"ag-grid-community/styles/ag-grid.css\";\nimport \"ag-grid-community/styles/ag-theme-quartz.css\";\n\nconst metaRenderer = params => {\n if (params.value.ontology) {\n return <a href={`http://purl.obolibrary.org/obo/${params.value.id.replace(\":\",\"_\")}`} target='_blank'>{params.value.label}</a>\n }\n return params.value.label\n}\nconst sampleRenderer = params => {\n const sampleMeta = params.value;\n return JSON.stringify(sampleMeta,null,2);\n}\nconst Study = props => {\n let samples = props.expressionSamples[props.id];\n let sampleMetadata = [];\n let metadataFields = [{ field: \"sampleId\", cellRenderer: sampleRenderer }];\n let isFactor={};\n samples.forEach((sample, idx) => {\n if (idx === 0) {\n let factors = {\n headerName: 'Experimental Variables',\n children: []\n }\n sample.factor.forEach(factor => {\n factors.children.push({field: factor.type, cellRenderer: metaRenderer})\n isFactor[factor.type] = true;\n });\n metadataFields.push(factors);\n let characteristics = {\n headerName: 'Sample Characteristics',\n children: []\n }\n sample.characteristic.forEach(ch => {\n if (!isFactor[ch.type]) {\n characteristics.children.push({field: ch.type, cellRenderer: metaRenderer})\n }\n });\n metadataFields.push(characteristics)\n }\n let s_info = {sampleId: sample}\n sample.factor.forEach(factor => {\n s_info[factor.type] = {label: factor.label};\n if (factor.ontology) {\n s_info[factor.type]['ontology'] = factor.ontology\n s_info[factor.type]['id'] = factor.id;\n }\n })\n sample.characteristic.forEach(ch => {\n s_info[ch.type] = {label: ch.label};\n if (ch.ontology) {\n s_info[ch.type]['ontology'] = ch.ontology\n s_info[ch.type]['id'] = ch.id;\n }\n })\n sampleMetadata.push(s_info)\n })\n const [rowData, setRowData] = useState(sampleMetadata);\n const [colDefs, setColDefs] = useState(metadataFields);\n const defaultColDef = useMemo(() => {\n return {\n filter: true\n }\n }, []);\n return (\n <div>\n <div className=\"ag-theme-quartz\" style={{height: `${44 * (samples.length + 2)}px`}}>\n <AgGridReact rowData={rowData} columnDefs={colDefs} defaultColDef={defaultColDef}/>\n </div>\n <a href={`https://www.ebi.ac.uk/gxa/experiments/${props.id}`}>EBI Atlas Experiment: {props.id}</a>\n </div>\n );\n};\nexport default connect(\n 'selectExpressionSamples',\n 'doToggleExpressionSample',\n Study);\n"],"names":[],"version":3,"file":"Study.826d318c.js.map"}