-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
471 lines (438 loc) · 30.7 KB
/
index.html
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="plco.js"></script>
<script src="plcoHTMLElements.js"></script>
<script src="index.js"></script>
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<style>
.tabsMessage {
font-size: xx-large;
}
.tabsRadio:checked+.tabsLabel {
font-weight: bolder;
color: #6EE7B7;
border-bottom: 4px solid #6EE7B7;
}
.tabsRadio:checked+.tabsLabel+.tabsContent {
display: flex;
}
.plotHoverDivs {
top: 800px;
left: 500px;
}
.loader {
border: 16px solid #3498db;
border-top: 16px solid #3498db;
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
position: absolute;
z-index: 10;
top: 800px;
left: 50%;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
a {
text-decoration: underline;
text-decoration-color: transparent;
transition: 500ms;
}
a:hover {
text-decoration-color: inherit;
}
select {
border: 2px solid black;
}
#resultsCheckbox:checked~#labelDown{
display: none;
}
#resultsCheckbox:checked~#labelUp{
display: inline-block;
}
#resultsCheckbox:checked~#fullResults{
display: inline-block;
}
.explorePhenotypesNav {
animation: gradient 1s ease infinite, grow 1s ease-in-out infinite;
background: linear-gradient(-46deg, #6EE7B7, #6bb3e4);
background-size: 400% 400%;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 50% 100%;
}
100% {
background-position: 0% 50%;
}
}
@keyframes grow {
0% {
transform: scale(1);
}
50% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
</style>
<title>PLCOjs SDK Explorer</title>
</head>
<body class="divide-y-2 divide-gray-200" onload="
plco.explorePhenotypes(false, false, true, 'explorePhenotypes', {width: undefined}, {responsive: true});
let url = new URL(window.location.href);
let phenotype_ids = url.searchParams.get('id');
let sexes = url.searchParams.get('sex');
let ancestries = url.searchParams.get('ancestry');
if (url && sexes && ancestries) {
document.querySelectorAll('nav ul li a')[2].click();
let textarea = document.querySelector('#plotContainer textarea');
let values = JSON.parse(textarea.value);
phenotype_ids = phenotype_ids.split(',').map(id => Number.parseInt(id))
sexes = sexes.split(',');
ancestries = ancestries.split(',');
for (let i = 0; i < phenotype_ids.length; i++) {
values.push({phenotype_id: phenotype_ids[i], sex: sexes[i], ancestry: ancestries[i]})
}
textarea.value = JSON.stringify(values);
document.querySelector('#plotContainer form button[type=submit]').click();
}
"
>
<header class="bg-gradient-to-b from-white">
<div class="text-2xl flex flex-row items-center justify-start flex-wrap">
<span class="text-3xl md:text-5xl font-extrabold m-4 text-red-900 flex-shrink-0" style="font-family: fantasy;">PLCO<sub style="color:green"><a href="https://bootcamp.berkeley.edu/blog/most-in-demand-programming-languages" target="_blank">js</a></sub> SDK Explorer</span>
<sup class="font-semibold md:text-lg text-sm pr-2 text-green-600"><a href="https://dceg.cancer.gov/" target="_blank">DCEG</a></sup>
<div>
<span class="md:text-lg text-sm text-black">
[<a href="https://github.com/episphere/plco" target="_blank" class="text-blue-600">code</a>]
[<a href="https://pubmed.ncbi.nlm.nih.gov/35900159/" target="_blank" class="text-blue-600" style="background-color:yellow">publication</a>]
[<a href="https://episphere.github.io/plco/docs" target="_blank" class="text-blue-600">documentation</a>]
[<a href="https://observablehq.com/@episphere/plcojs" target="_blank" class="text-blue-600">tutorial</a>]
[<a href="https://observablehq.com/@ericr491/plco-sdk" target="_blank" class="text-blue-600">notebook</a>]
[<a href="https://gitter.im/episphere/plco" target="_blank" class="text-blue-600">gitter</a>]
[<a href="https://www.youtube.com/watch?v=wtieipSYvTY" target="_blank" class="text-red-600">Project presentation</a>]
[<a href="https://youtu.be/87dXT9YtbfY" target="_blank" class="text-red-600">Tutorial Webcast</a>]
[<a href="https://dceg.cancer.gov/research/who-we-study/cohorts/prostate-lung-colon-ovary-prospective-study" target="_blank" class="text-blue-600">about</a>]
</span>
</div>
</div>
<nav class>
<ul class="w-full md:flex text-center">
<li class="md:m-4 my-2 mx-4 md:text-xl text-md font-bold border-black border-2 rounded-3xl hover:bg-green-300"><a href="#" class="block md:p-2 py-2 px-4" onclick="document.getElementById('homeContainer').style = '';document.getElementById('exploreContainer').style = 'display:none';document.getElementById('plotContainer').style = 'display:none;';document.getElementById('otherContainer').style = 'display:none;';document.getElementById('bugContainer').style='display:none;';">Home</a></li>
<li class="md:m-4 my-2 mx-4 md:text-xl text-md font-bold border-black border-2 rounded-3xl hover:bg-green-300"><a href="#" class="block md:p-2 py-2 px-4" onclick="document.getElementById('homeContainer').style = 'display:none;';document.getElementById('exploreContainer').style = '';document.getElementById('plotContainer').style = 'display:none;';document.getElementById('otherContainer').style = 'display:none;';document.getElementById('bugContainer').style='display:none;';">Phenotype IDs</a></li>
<li class="md:m-4 my-2 mx-4 md:text-xl text-md font-bold border-black border-2 rounded-3xl hover:bg-green-300"><a href="#" class="block md:p-2 py-2 px-4" onclick="document.getElementById('homeContainer').style = 'display:none;';document.getElementById('exploreContainer').style = 'display:none;';document.getElementById('plotContainer').style = '';document.getElementById('otherContainer').style = 'display:none;';document.getElementById('bugContainer').style='display:none;';">Explore Plots</a></li>
<li class="md:m-4 my-2 mx-4 md:text-xl text-md font-bold border-black border-2 rounded-3xl hover:bg-green-300"><a href="#" class="block md:p-2 py-2 px-4" onclick="document.getElementById('homeContainer').style = 'display:none;';document.getElementById('exploreContainer').style = 'display:none;';document.getElementById('plotContainer').style = 'display:none;';document.getElementById('otherContainer').style = '';document.getElementById('bugContainer').style='display:none;';if(!visited) {document.getElementById('otherContainer').innerHTML = otherContainerContents;}visited = true;">Custom Elements</a></li>
<li class="md:m-4 my-2 mx-4 md:text-xl text-md font-bold border-black border-2 rounded-3xl hover:bg-green-300"><a href="#" class="block md:p-2 py-2 px-4" onclick="window.open('https://exploregwas.cancer.gov/plco-atlas/#/gwas/summary')">GWAS Explorer</a></li>
</ul>
</nav>
</header>
<div class="bg-white flex flex-col max-w-8xl p-6 mx-10" id='homeContainer'>
<h2 style="color:maroon;font-size:x-large"><b>PLCO</b></h2>
<p style="color:navy;font-size:large">
<a href="https://dceg.cancer.gov/research/who-we-study/cohorts/prostate-lung-colon-ovary-prospective-study" target="_blank" style="color:blue">PLCO is a large NCI trial</a> (n=155,000) that, since 1993 evaluated screening for early detection of prostate, lung, colon, and ovarian cancer.
In 2021-2022, summary GWAS data (no individual data!) was made available in the public domain with an <a href="https://exploregwas.cancer.gov/plco-atlas/#/api-access" target="_blank" style="color:blue">Application Programming Interface (API)</a>.
This creates the opportinity to facilitate data retrieval from a variety of programming languages and analytical environments by developing the corresponding Software Development Kits (SDK).
</p>
<h2 style="color:maroon;font-size:x-large"><b>This is not the data portal</b></h2>
<p style="color:navy;font-size:large">
You could develop a data portal using PLCOjs and other libraries mediating access to one or more data sources of interrest. Instead, PLCOjs is a JavaScript SDK developed to provide programatic interoperability with <a href="https://exploregwas.cancer.gov/plco-atlas/#/api-access" target="_blank" style="color:blue">PLCO's public APIs</a>. This developemnt effort was pursued by modularizing <a href="https://exploregwas.cancer.gov/plco-atlas" target="_blank" style="color:blue">PLCO's Data portal</a> graphic plotting and data retrieval components.
The rationale is that PLCO data analytics might be integrated with a variety of GWAS data processing applications. This integration is overviewed in the <b><a href="https://observablehq.com/@episphere/plcojs" target="_blank" style="color:blue">tutorial</a><sup>[<a href="https://youtu.be/87dXT9YtbfY" target="_blank" style="color:red">YouTube</a>]</sup></b>, the suggested starting point to uderstand PLCOjs.
</p>
<h2 style="color:maroon;font-size:x-large"><b>FAIR</b></h2>
<p style="color:navy;font-size:large">
Let's find out how Findable, Accessible, Interoperable and, most defining, Reusable, are the data objects generated by PLCOjs:
<li style="color:navy;font-size:large">If I place my data in a versioned host as in <a href="https://jonasalmeida.github.io/pub/PLCOpca2.json" target="_blank" style="color:blue">jonasalmeida.github.io/pub/PLCOpca2.json</a> ...</li>
<li style="color:navy;font-size:large">... would I be able to also recover the interactive plot with a URL shortner, such as <a href="https://bit.ly/plcopca" target="_blank" style="color:blue">bit.ly/plcopca</a>?</li>
<p style="color:maroon;font-size:x-large"><b>Give it a try!</b></p>
<p style="color:navy;font-size:large">
Note the <i>plco.js</i> library is also loaded in this page. You can experiment with <a href="https://episphere.github.io/plco/docs/plco.plot.html" target="_blank" style="color:blue">different plots</a> from the devTools by copy/pasting the example code snippets to the console. The one below was created with:
</p>
<p style="color:purple">
plco.plot.qq2('plot', [{phenotype_id:3080, sex:'female', ancestry:'east_asian'}, {phenotype_id:3080, sex:'female', ancestry:'european'}, {phenotype_id: 3550, sex:'all', ancestry:'east_asian'}])
</p>
</div>
<div class="bg-white flex flex-col max-w-8xl p-6 pb-12 mx-10" id='exploreContainer' style="display: none;">
<span class="text-lg md:text-3xl font-semibold text-red-900">Phenotype codes</span>
<span>The primary use of this plot is to highlight the hierarchy between phenotype codes. For a quick exploration of existing data see <a href="https://www.youtube.com/watch?v=wtieipSYvTY" target="_blank" style="color:blue">this presentation first</a>.</span>
<div class="flex flex-col items-center md:my-16 my-4 w-auto h-auto" id='explorePhenotypes'></div>
<div class="flex flex-col items-center w-auto h-auto" id='explorePhenotypestable'></div>
<span class="text-lg md:text-3xl font-semibold text-red-900">Additional data available.</span>
<span class="mb-4" style="font-size:small">Only the phenotypes highlighted in red are garanteed to have additional data. For others, it varies.</span>
<form onsubmit="
let formatJson = (jsonArray, spacing) => {
let s = '['
for (let json of jsonArray) {
s += formatJsonHelper(json, spacing + 4)
}
return s + '<br>]'
};
let formatJsonHelper = (json, spacing) => {
let s = '<br>' + `<span class='text-opacity-0 text-white select-none'>${'*'.repeat(spacing)}</span>` + '{'
for (let key in json) {
if (json[key] === null) {
continue
}
if (key === 'count' && json[key] != 0) {
s += '<br>' + `<span class='text-opacity-0 text-white select-none'>${'*'.repeat(spacing + 4)}</span>` + `<span class='bg-red-300'>` + key + ' : ' + json[key] + '</span>,'
continue
}
if (typeof json[key] === 'object') {
s += formatJsonHelper(json[key], spacing + 4)
} else {
s += '<br>' + `<span class='text-opacity-0 text-white select-none'>${'*'.repeat(spacing + 4)}</span>` + key + ' : ' + json[key] + ','
}
}
s += '<br>' + `<span class='text-opacity-0 text-white select-none'>${'*'.repeat(spacing)}</span>` + '},'
return s
};
plco.api.get('metadata', {chromosome: 'all', phenotype_id: Number.parseInt(document.getElementById('checkPhenotypeMetadata').value)})
.then(data => document.getElementById('fullResults').innerHTML = formatJson(data, 0))
.then(_ => document.getElementById('resultsCheckbox').checked = true);
return false;
">
<label for="checkPhenotypeMetadata">Enter Phenotype ID (for example, try 3080 for Breast Cancer, or 7470 for Rheumatoid Arthritis): </label>
<input type="number" id="checkPhenotypeMetadata" required class="focus:ring-2 focus:ring-blue-600 focus:outline-none block border border-black md:w-1/4 w-full mb-2">
<button type="submit" class="border-2 border-black rounded-xl p-1 px-2 mt-4 mr-4 hover:bg-green-400">Submit</button>
</form>
<div id="results" class="w-full relative">
<span class="right-1/2 top-0 absolute inline-block p-2 text-lg font-bold">Results</span>
<input type="checkbox" id="resultsCheckbox" class="hidden">
<label for="resultsCheckbox" id="labelDown" class="inline-block absolute top-0 right-0">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</label>
<label for="resultsCheckbox" id="labelUp" class="hidden absolute top-0 right-0">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
</svg>
</label>
<span id="fullResults" class="hidden m-8 mb-0 md:break-normal break-all">👻</span>
</div>
-->
</div>
<div class="bg-white flex flex-col max-w-8xl p-6 mx-10" id='plotContainer' style="display: none;">
<datalist id='sexValues'>
<option value='all'>
<option value='female'>
<option value='male'>
</datalist>
<datalist id='ancestryValues'>
<option value='african_american'>
<option value='east_asian'>
<option value='european'>
</datalist>
<form onsubmit="
document.querySelectorAll('.shareButton').forEach(button => button.style.display = 'none')
let arr = JSON.parse(document.getElementById('textarea1').value);
let tabsContainer = document.querySelectorAll('.tabsContent')
let tabsMessages = document.querySelectorAll('.tabsMessage')
try {
tabsMessages.forEach(tab => tab.innerHTML = 'Loading...')
if (arr.length == 0) {
throw new SyntaxError('No inputs were given');
} else if (arr.length == 1) {
const {phenotype_id, sex, ancestry} = arr[0]
Promise.all([
plco.plot.manhattan('manhattan', phenotype_id, sex, ancestry, 2, undefined, false, {}, {}).catch(e => {tabsMessages[0].innerHTML = e.message;}),
plco.plot.qq('qq', phenotype_id, sex, ancestry, false, {legend: {orientation: 'v', x: 0.0, y: 1.2}, width: undefined}, {responsive: true}).catch(e => {tabsMessages[1].innerHTML = e.message;}),
plco.plot.pca('pca', phenotype_id, sex, ancestry, false, {}, {}).catch(e => {tabsMessages[2].innerHTML = e.message;})
])
.then(_ => {tabsMessages.forEach(tab => {if (tab.innerHTML.includes('Loading...')) tab.innerHTML = ''})})
} else {
Promise.all([
plco.plot.manhattan2('manhattan', arr, 2, undefined, false, {}, {}).catch(e => tabsMessages[0].innerHTML = e.message),
plco.plot.qq2('qq', arr, false, {legend: {orientation: 'v', x: 0.0, y: 1.2}, width: undefined}, {responsive: true}).catch(e => tabsMessages[1].innerHTML = e.message),
plco.plot.pca2('pca', arr, false, {}, {}).catch(e => tabsMessages[2].innerHTML = e.message),
])
.then(_ => {tabsMessages.forEach(tab => {if (tab.innerHTML.includes('Loading...')) tab.innerHTML = ''})})
}
} catch(e){
if (e instanceof SyntaxError) {
tabsMessages.forEach(function(tab) {tab.innerHTML = e.message })
}
}
finally {
document.querySelectorAll('.shareButton').forEach(button => button.style.display = '')
return false;
}">
<span class="text-lg md:text-3xl font-semibold text-red-900 block">Plotting by population stratification</span>
<span>See also <a href="https://episphere.github.io/plco/docs/plco.plot.html" target="_blank" style="color:blue">Plot Documentation</a>.</span>
<span>The primary use of this panel is to generate multiple plots for each statification (Manhattan, PCA and QQ). For exmples see <a href="https://www.youtube.com/watch?v=wtieipSYvTY" target="_blank" style="color:blue">this presentation</a> first.</span>
<span>The first textarea contains a collection of <b>phenotype id</b>, <b>sex</b>, and <b>ancestry</b> inputs to be plotted. It is initally empty, and you may add more inputs by filling out the input boxes as needed, and pressing the <b>Add</b> button. Finally, press <b>Submit</b> to see your plots! Do note that manhattan plot only supports 1 or 2 inputs, while qq and pca plot supports more than 2 inputs.</span>
<textarea id="textarea1" readonly="true" class="block border border-black w-full my-4 text-sm">[ ]</textarea>
<label for='enterPhenotype' class="block text-lg">Enter Phenotype ID: <sup class="text-red-600">*</sup></label>
<input type="number" id='enterPhenotype' class="focus:ring-2 focus:ring-blue-600 focus:outline-none block border border-black md:w-1/4 w-full mb-2">
<label for='enterSex' class="block text-lg">Enter Sex: <sup class="text-red-600">*</sup></label>
<input list="sexValues" type="text" id='enterSex' class="focus:ring-2 focus:ring-blue-600 focus:outline-none block border border-black md:w-1/4 w-full mb-2">
<label for='enterAncestry' class="block text-lg">Enter Ancestry: <sup class="text-red-600">*</sup></label>
<input list="ancestryValues" type="text" id='enterAncestry' class="focus:ring-2 focus:ring-blue-600 focus:outline-none block border border-black md:w-1/4 w-full mb-2">
<button class="border-2 border-black rounded-xl p-1 px-2 mt-4 mr-4 hover:bg-blue-400" onclick="let content = JSON.parse(document.getElementById('textarea1').value); let id = Number.parseInt(document.getElementById('enterPhenotype').value);let sex = (document.getElementById('enterSex').value);let ancestry = (document.getElementById('enterAncestry').value); content.push({phenotype_id: id, sex, ancestry}); document.getElementById('textarea1').value = JSON.stringify(content); return false;">Add</button>
<button type="reset" class="border-2 border-black rounded-xl p-1 px-2 mt-4 mr-4 hover:bg-red-400">Reset</button>
<button type="submit" class="border-2 border-black rounded-xl p-1 px-2 mt-4 mr-4 hover:bg-green-400">Submit</button>
</form>
<div class="mt-20 mb-10 subplotsContainer flex flex-wrap max-w-8xl justify-evenly items-stretch">
<input type="radio" class="tabsRadio hidden" name="plot" id="manhattanPlot" checked>
<label for="manhattanPlot" class="tabsLabel text-xl cursor-pointer p-5 bg-gray-100 flex-grow text-center rounded-tl-xl">Manhattan Plot</label>
<div id="manhattan" class="tabsContent order-1 w-full border-b-2 border-gray-400 hidden flex-col items-center">
<span class="tabsMessage order-first">
Waiting...
</span>
<button class="shareButton self-end order-last border-2 border-black rounded-xl p-1 px-2 m-4 mr-4 hover:bg-yellow-400" style="display: none;"
onclick="
let textarea = document.querySelector('#plotContainer textarea');
let value = JSON.parse(textarea.value);
let phenotype_ids = [];
let sexes = [];
let ancestries = [];
value.forEach(obj => {
phenotype_ids.push(obj.phenotype_id)
sexes.push(obj.sex)
ancestries.push(obj.ancestry)
});
phenotype_ids = phenotype_ids.join(',');
sexes = sexes.join(',');
ancestries = ancestries.join(',');
navigator.clipboard.writeText('https:\/\/episphere.github.io/plco/' + '?' + `id=${phenotype_ids}&sex=${sexes}&ancestry=${ancestries}`);
alert('URL copied to clipboard')
"
>Share URL (Copies to Clipboard)</button>
</div>
<input type="radio" class="tabsRadio hidden" name="plot" id="qqPlot">
<label for="qqPlot" class="tabsLabel text-xl cursor-pointer p-5 bg-gray-100 flex-grow text-center">QQ Plot</label>
<div id="qq" class="tabsContent order-1 w-full border-b-2 border-gray-400 hidden flex-col items-center">
<span class="tabsMessage order-first">
Waiting...
</span>
<button class="shareButton self-end order-last border-2 border-black rounded-xl p-1 px-2 m-4 mr-4 hover:bg-yellow-400" style="display: none;"
onclick="
let textarea = document.querySelector('#plotContainer textarea');
let value = JSON.parse(textarea.value);
let phenotype_ids = [];
let sexes = [];
let ancestries = [];
value.forEach(obj => {
phenotype_ids.push(obj.phenotype_id)
sexes.push(obj.sex)
ancestries.push(obj.ancestry)
});
phenotype_ids = phenotype_ids.join(',');
sexes = sexes.join(',');
ancestries = ancestries.join(',');
navigator.clipboard.writeText('https:\/\/episphere.github.io/plco/' + '?' + `id=${phenotype_ids}&sex=${sexes}&ancestry=${ancestries}`);
alert('URL copied to clipboard')
"
>Share URL (Copies to Clipboard)</button>
</div>
<input type="radio" class="tabsRadio hidden" name="plot" id="pcaPlot">
<label for="pcaPlot" class="tabsLabel text-xl cursor-pointer p-5 bg-gray-100 flex-grow text-center rounded-tr-xl">PCA Plot</label>
<div id="pca" class="tabsContent order-1 w-full border-b-2 border-gray-400 hidden flex-col items-center">
<span class="tabsMessage order-first">
Waiting...
</span>
<button class="shareButton self-end order-last border-2 border-black rounded-xl p-1 px-2 m-4 mr-4 hover:bg-yellow-400" style="display: none;"
onclick="
let textarea = document.querySelector('#plotContainer textarea');
let value = JSON.parse(textarea.value);
let phenotype_ids = [];
let sexes = [];
let ancestries = [];
value.forEach(obj => {
phenotype_ids.push(obj.phenotype_id)
sexes.push(obj.sex)
ancestries.push(obj.ancestry)
});
phenotype_ids = phenotype_ids.join(',');
sexes = sexes.join(',');
ancestries = ancestries.join(',');
navigator.clipboard.writeText('https:\/\/episphere.github.io/plco/' + '?' + `id=${phenotype_ids}&sex=${sexes}&ancestry=${ancestries}`);
alert('URL copied to clipboard')
"
>Share URL (Copies to Clipboard)</button>
</div>
</div>
</div>
<div class="bg-white flex flex-col max-w-8xl p-6 mx-10" id='otherContainer' style="display: none;">
<span class="text-lg md:text-3xl font-semibold text-red-900 block">Demostrating support with the <a href="https://episphere.github.io/plotly" style="color:blue">Epi-Plotly library</a>.</span>
<span class="text-green-500 text-md">Pros: Great for static plots; faster due to not having to fetch API data; no JavaScript code needed;</span>
<span class="text-red-500 text-md">Cons: As of now, the json file must be hosted; </span>
<epi-plotly>https://episphere.github.io/plco/plot.json</epi-plotly>
<br>
<span class="text-lg">Steps to recreate:</span>
<ol class="list-decimal">
<li class="mx-6">Set the to_json parameter to true in any of the graphing methods. E.g.: plco.plot.qq('', 3080, 'female', 'east_asian', true)</li>
<li class="mx-6">Call it and then parse the results using JSON.parse(...)</li>
<li class="mx-6">Pass the JS object into plco.downloadJSON(your_obj)</li>
<li class="mx-6">Host the downloaded *.json file anywhere that supports raw files. E.g.: Github, Google Drive, Your Web Server</li>
</ol>
<br>
<span class="text-lg">Tips:</span>
<span>You can add Plotly event listeners by querying the div with js-plotly-plot class nested within the epi-plotly tag.</span>
<br>
<span class="text-lg md:text-3xl font-semibold text-red-900 block">An alternative to <a href="https://episphere.github.io/plotly" style="color:blue">Epi-Plotly library</a>.</span>
<span>Insert this into the header: <br> <script src="https://episphere.github.io/plco/plcoHTMLElements.js"></script> <br><br> 3 plotting tags available:</span>
<ul class="text-lg md:text-xl text-red-900 block">
<li>
<manhattan-plot></manhattan-plot>
</li>
<li>
<qq-plot></qq-plot>
</li>
<li>
<pca-plot></pca-plot>
</li>
</ul><br>
<span>All three plotting tags have the following attributes available: data-inputs, custom-layout, custom-config</span><br>
<span>Example: (Notice that for <span class="text-blue-500">data-inputs</span> each object is separated by a semi-colon)</span><br>
<span> <manhattan-plot <span class="text-blue-500">data-inputs</span>="[{phenotype_id: 3080, sex: female, ancestry: european}; {phenotype_id:3080, sex: female, ancestry: east_asian}]" <span class="text-blue-500">custom-layout</span>="plot_bgcolor:#d3d3d3;paper_bgcolor:#fff" <span class="text-blue-500">custom-config</span>="scrollZoom:false" ></manhattan-plot> </span><br>
<span>The manhattan-plot have additionally <span class="text-blue-500">chromosome</span>=number and <span class="text-blue-500">p-val-nlog-min</span>=number attributes.</span>
<manhattan-plot style="border: 2px solid black;" data-inputs="[{phenotype_id: 3080, sex: female, ancestry:european}; {phenotype_id:3080, sex: female, ancestry: east_asian}]" custom-layout="plot_bgcolor:#d3d3d3;paper_bgcolor:#fff" custom-config="scrollZoom:false"></manhattan-plot> -->
</div>
<div class="bg-white flex flex-col max-w-8xl p-6 mx-10" id='bugContainer' style="display: none;">
<ol class="list-disc p-5 text-xl">
<li>🐛</li>
</ol>
</div>
<footer class="max-w-8xl p-6 mx-10 ">
<span class="text-xs text-gray-400 select-none">
<span class="block">
Credits: Eric Ruan, Erika Nemeth, Lorena Sandoval, Jonas Almeida
</span>
<span class="block">
Acknowledgments: Kevin Jiang, Brian Park, Kai-Ling Chen for building the PLCO API and plots for which this is based on
</span>
<span class="block">
Libraries: Plotly.js, localforage, tailwindcss
</span>
</span>
</footer>
<script>
(function() { // anonymously to avoid polluting the global scope
let li = document.querySelector('ul .explorePhenotypesNav')
setTimeout(_ => {
try{
li.classList.remove('explorePhenotypesNav')
li.style.backgroundColor = null
}catch(err){
// console.log(err)
}
}, 2500)
})()
</script>
<script>
plco.plot.qq2('plot', [{phenotype_id:3080, sex:'female', ancestry:'east_asian'}, {phenotype_id:3080, sex:'female', ancestry:'european'}, {phenotype_id: 3550, sex:'all', ancestry:'east_asian'}])
</script>
</body>
</html>