-
Notifications
You must be signed in to change notification settings - Fork 6
/
iNat_id_counts_by_iconic_taxa.html
148 lines (138 loc) · 6.83 KB
/
iNat_id_counts_by_iconic_taxa.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
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="iNaturalist Identification Counts by Iconic Taxa" />
<meta name="viewport" content="width=device-width, minimum-scale=0.6">
<title>iNaturalist Identification Counts by Iconic Taxa</title>
<style>
html,body { font:14px Sans-Serif; }
#main { width:100%; }
table, thead, tbody, tr, td, th { margin:0; padding:4px; border-width:1px 0px;border-style:solid; border-color:lightgray; border-spacing:0; border-collapse:collapse; }
th { position:-webkit-sticky /*Safari*/; position:sticky; top:0; font-weight:600; background:forestgreen; color:white; text-align:left; vertical-align:bottom; }
tr { background:whitesmoke; }
tr:nth-child(even) { background-color:white; }
.tar { text-align:right; }
a { text-decoration:none; color:royalblue; }
a:hover { background:lightgray; }
tfoot tr { font-weight:600; background:black; color:white; }
</style>
</head>
<body>
<script>
let winurlstr = window.location.href;
let winurlsearchstr = window.location.search;
let winurlexsearchstr = winurlstr.replace(winurlsearchstr,'');
let winurlparams = new URLSearchParams(winurlsearchstr.substring(1));
//let p_per_page = winurlparams.get('per_page') || 10;
//let p_page = winurlparams.get('page') || 1;
winurlparams.delete('per_page');
winurlparams.set('per_page',0); // set to 0 since we need only total record counts, not details.
winurlparams.delete('iconic_taxon_id');
function furl(url,txt=url) { return '<a href="'+url+'">'+txt+'</a>'; };
function famp(str) { return str.replace(/&/g,'&'); };
function fcomnum(n) { return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g,',') };
function fpct(d,p=1) {
x = d*100;
return x.toFixed(p);
};
function faddelem(etype,eparent=null,eattributes={}) {
let eobj = document.createElement(etype);
for (let [key,value] of Object.entries(eattributes)) {
if ( typeof value === 'object' && value !== null ) {
for (let [subkey,subvalue] of Object.entries(value)) { eobj[key][subkey] = subvalue; };
}
else { eobj[key] = value; };
};
if (eparent) { eparent.appendChild(eobj); };
return eobj;
};
function faddelems(etype,eparent=null,eattributes=[]) { for (let e of eattributes) { faddelem(etype,eparent,e); }; };
function fsettdvalue(rlabel,clabel,val) { document.getElementById(rlabel+'_'+clabel).innerHTML = val; };
function fgetcount(url) {
return fetch(url)
.then((response) => {
if (!response.ok) { throw new Error(response.status+': '+response.statusText); };
return response.json();
})
.then((data) => { return data.total_results; })
.catch((err) => { console.error(err); });
};
let apibase = 'https://api.inaturalist.org/v1/identifications';
let apiurl = apibase+((winurlparams!='')?('?'+winurlparams):'');
let apirefurl = 'https://api.inaturalist.org/v1/docs/#!/Identifications/get_identifications';
let apirefname = 'iNaturalist Identifications Search';
let apiref = furl(apirefurl,apirefname);
let pagetitle = document.title;
faddelem('h1',document.body,{innerText:pagetitle});
faddelem('p',document.body,{innerHTML:'This is the base query: '+furl(famp(apiurl))+'. (This page will accept most parameters from the '+apiref+' API endpoint.)'});
const cOther = 'Other (Unknown)';
const cTotal = 'All';
var ary_it = [
{icon_taxa:"Mammalia",disp_name:"Mammals",id:40151,icon:"🐒",fetch:true,color:"mediumblue"},
{icon_taxa:"Aves",disp_name:"Birds",id:3,icon:"🦅",fetch:true,color:"blue"},
{icon_taxa:"Reptilia",disp_name:"Reptiles",id:26036,icon:"🐍",fetch:true,color:"darkblue"},
{icon_taxa:"Amphibia",disp_name:"Amphibians",id:20978,icon:"🐸",fetch:true,color:"navy"},
{icon_taxa:"Actinopterygii",disp_name:"Ray-Finned Fish",id:47178,icon:"🐠",fetch:true,color:"midnightblue"},
{icon_taxa:"Mollusca",disp_name:"Mollusks",id:47115,icon:"🐌",fetch:true,color:"orangered"},
{icon_taxa:"Insecta",disp_name:"Insects",id:47158,icon:"🐞",fetch:true,color:"red"},
{icon_taxa:"Arachnida",disp_name:"Arachnids",id:47119,icon:"🕷",fetch:true,color:"crimson"},
{icon_taxa:"Animalia",disp_name:"Other Animals",id:1,icon:"🦀",fetch:true,color:"royalblue"},
{icon_taxa:"Plantae",disp_name:"Plants",id:47126,icon:"🌱",fetch:true,color:"green"},
{icon_taxa:"Fungi",disp_name:"Fungi",id:47170,icon:"🍄",fetch:true,color:"magenta"},
{icon_taxa:"Chromista",disp_name:"Chromista",id:48222,fetch:true,color:"saddlebrown"},
{icon_taxa:"Protozoa",disp_name:"Protozoa",id:47686,fetch:true,color:"purple"},
{icon_taxa:"Other",disp_name:cOther,id:48460,fetch:false,color:"gray"},
{icon_taxa:"All",disp_name:cTotal,icon:"🌐",fetch:true,color:"none"},
];
let table = faddelem('table',document.body,{id:'main'});
let thead = faddelem('thead',table);
let hrow = faddelem('tr',thead);
let labels = [
{innerText:'Category'},
{},
{classList:'tar',innerText:'Count'},
{classList:'tar',innerText:'% of All'},
];
faddelems('th',hrow,labels);
let tbody = faddelem('tbody',table);
let tfoot = faddelem('tfoot',table);
let data = [];
for (let iconic_taxon of ary_it) {
let description = iconic_taxon.disp_name;
let param_value = iconic_taxon.id;
let row = faddelem('tr',(description===cTotal)?tfoot:tbody);
let values = [
{innerText:description},
{innerText:iconic_taxon.icon||''},
{classList:'tar',id:description+'_count'},
{classList:'tar',id:description+'_pct'},
];
faddelems('td',row,values);
if (iconic_taxon.fetch) {
if (param_value) { winurlparams.set('iconic_taxon_id',param_value); }
else { winurlparams.delete('iconic_taxon_id'); };
let prom0 = Promise.resolve(description);
let prom1 = fgetcount(apibase+'?'+winurlparams);
Promise.all([prom0,prom1]).then(results=>{
let cat = results[0];
let count = results[1] || 0;
fsettdvalue(cat,'count',fcomnum(count));
data.push({iconic_taxon:cat,count:count});
//if this is the last count to be returned, go on and calculate the "Other" iconic taxon count, and then calculate percents for all categories
if (data.length===(ary_it.filter(v=>v.fetch).length)) {
let ttlcount = data.filter(d=>d.iconic_taxon===cTotal)[0].count;
let plug = data.filter(d=>d.iconic_taxon!==cTotal).reduce((cum,curr)=>cum-curr.count,ttlcount); // subtract non-total counts from total count
fsettdvalue(cOther,'count',fcomnum(plug));
data.push({iconic_taxon:cOther,count:plug});
for (p of data) {
p['pct'] = ttlcount?p.count/ttlcount:null;
fsettdvalue(p.iconic_taxon,'pct',ttlcount?fpct(p.count/ttlcount):'N/A');
};
};
});
};
};
</script>
</body>
</html>