@macrostrat/map-interface 1.3.2 → 1.4.1
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.
- package/CHANGELOG.md +19 -0
- package/dist/cjs/index.js +4 -4
- package/dist/cjs/{map-interface.3934d6d6.js → map-interface.10d442f4.js} +2 -2
- package/dist/cjs/{map-interface.3934d6d6.js.map → map-interface.10d442f4.js.map} +1 -1
- package/dist/cjs/{map-interface.f1eec151.js → map-interface.28d1a6b7.js} +7 -6
- package/dist/cjs/map-interface.28d1a6b7.js.map +1 -0
- package/dist/cjs/{map-interface.853e0edd.js → map-interface.3bc4f731.js} +2 -2
- package/dist/cjs/{map-interface.853e0edd.js.map → map-interface.3bc4f731.js.map} +1 -1
- package/dist/cjs/{map-interface.e7194f92.js → map-interface.7bdbe4b6.js} +59 -47
- package/dist/cjs/map-interface.7bdbe4b6.js.map +1 -0
- package/dist/cjs/{map-interface.5813e876.js → map-interface.cf6c9a68.js} +5 -5
- package/dist/cjs/{map-interface.5813e876.js.map → map-interface.cf6c9a68.js.map} +1 -1
- package/dist/cjs/{map-interface.1d19056e.js → map-interface.dcbd3874.js} +4 -2
- package/dist/cjs/map-interface.dcbd3874.js.map +1 -0
- package/dist/esm/index.d.ts +18 -38
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +4 -4
- package/dist/esm/{map-interface.e5349e97.js → map-interface.54ccd41f.js} +2 -2
- package/dist/esm/{map-interface.e5349e97.js.map → map-interface.54ccd41f.js.map} +1 -1
- package/dist/esm/{map-interface.25a708b1.js → map-interface.90d9023c.js} +2 -2
- package/dist/esm/{map-interface.25a708b1.js.map → map-interface.90d9023c.js.map} +1 -1
- package/dist/esm/{map-interface.9ce3d553.js → map-interface.ca1ee406.js} +61 -49
- package/dist/esm/map-interface.ca1ee406.js.map +1 -0
- package/dist/esm/{map-interface.e1493866.js → map-interface.e20a9bac.js} +4 -2
- package/dist/esm/map-interface.e20a9bac.js.map +1 -0
- package/dist/esm/{map-interface.f4e2f84e.js → map-interface.ec2278ab.js} +7 -6
- package/dist/esm/map-interface.ec2278ab.js.map +1 -0
- package/dist/esm/{map-interface.45814073.js → map-interface.f7b8bdb7.js} +5 -5
- package/dist/esm/{map-interface.45814073.js.map → map-interface.f7b8bdb7.js.map} +1 -1
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/dist/node/{map-interface.eb663cae.js → map-interface.33b7734a.js} +2 -2
- package/dist/node/map-interface.33b7734a.js.map +1 -0
- package/dist/node/map-interface.56b5b2ee.js +2 -0
- package/dist/node/map-interface.56b5b2ee.js.map +1 -0
- package/dist/node/{map-interface.cf540298.js → map-interface.6184dc0f.js} +2 -2
- package/dist/node/{map-interface.cf540298.js.map → map-interface.6184dc0f.js.map} +1 -1
- package/dist/node/map-interface.7aaa58c9.js +2 -0
- package/dist/node/map-interface.7aaa58c9.js.map +1 -0
- package/dist/node/{map-interface.55fa679c.js → map-interface.7e13bea8.js} +2 -2
- package/dist/node/{map-interface.55fa679c.js.map → map-interface.7e13bea8.js.map} +1 -1
- package/dist/node/map-interface.ce86a010.js +2 -0
- package/dist/node/map-interface.ce86a010.js.map +1 -0
- package/package.json +4 -4
- package/src/dev/map-page.ts +25 -19
- package/src/helpers.ts +4 -4
- package/src/location-panel/header.ts +2 -5
- package/src/map-panel/components/buttons.module.styl +5 -0
- package/src/map-panel/components/buttons.ts +56 -0
- package/src/map-panel/components/card.module.styl +43 -0
- package/src/map-panel/components/closeable-card.ts +64 -0
- package/src/map-panel/components/docs.module.styl +93 -0
- package/src/map-panel/components/docs.ts +92 -0
- package/src/map-panel/components/info-blocks.module.styl +39 -0
- package/src/map-panel/components/info-blocks.ts +88 -0
- package/src/map-panel/components/info-drawer/fossil-collections/collections.tsx +156 -0
- package/src/map-panel/components/info-drawer/fossil-collections/index.ts +21 -0
- package/src/map-panel/components/info-drawer/fossil-collections/main.module.sass +16 -0
- package/src/map-panel/components/info-drawer/index.ts +117 -0
- package/src/map-panel/components/info-drawer/macrostrat-linked.ts +399 -0
- package/src/map-panel/components/info-drawer/main.module.styl +67 -0
- package/src/map-panel/components/info-drawer/physiography.ts +29 -0
- package/src/map-panel/components/info-drawer/reg-strat.ts +74 -0
- package/src/map-panel/components/info-drawer/xdd-panel/Article.tsx +69 -0
- package/src/map-panel/components/info-drawer/xdd-panel/Journal.tsx +48 -0
- package/src/map-panel/components/info-drawer/xdd-panel/index.ts +69 -0
- package/src/map-panel/components/transitions/index.ts +24 -0
- package/src/map-panel/components/transitions/main.module.styl +55 -0
- package/src/map-panel/utils/formatting.ts +14 -0
- package/src/map-panel/utils/fossils.ts +209 -0
- package/src/map-panel/utils/index.ts +157 -0
- package/src/map-view.ts +77 -52
- package/dist/cjs/map-interface.1d19056e.js.map +0 -1
- package/dist/cjs/map-interface.e7194f92.js.map +0 -1
- package/dist/cjs/map-interface.f1eec151.js.map +0 -1
- package/dist/esm/map-interface.9ce3d553.js.map +0 -1
- package/dist/esm/map-interface.e1493866.js.map +0 -1
- package/dist/esm/map-interface.f4e2f84e.js.map +0 -1
- package/dist/node/map-interface.20c346ba.js +0 -2
- package/dist/node/map-interface.20c346ba.js.map +0 -1
- package/dist/node/map-interface.bc0fb98b.js +0 -2
- package/dist/node/map-interface.bc0fb98b.js.map +0 -1
- package/dist/node/map-interface.d9814996.js +0 -2
- package/dist/node/map-interface.d9814996.js.map +0 -1
- package/dist/node/map-interface.eb663cae.js.map +0 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { Collapse, Button } from "@blueprintjs/core";
|
|
3
|
+
import { AuthorList } from "@macrostrat/ui-components";
|
|
4
|
+
import h from "@macrostrat/hyper";
|
|
5
|
+
|
|
6
|
+
function Article(props) {
|
|
7
|
+
const [expanded, setExpanded] = useState(false);
|
|
8
|
+
const { data } = props;
|
|
9
|
+
|
|
10
|
+
const toggleExpand = () => {
|
|
11
|
+
setExpanded(!expanded);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Attempt to pull out only the year and not the whole date
|
|
15
|
+
let year;
|
|
16
|
+
try {
|
|
17
|
+
year = data.coverDate ? data.coverDate.match(/\d{4}/)[0] : "";
|
|
18
|
+
} catch (e) {
|
|
19
|
+
year = "";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const authors = data?.authors?.split("; ") ?? [];
|
|
23
|
+
|
|
24
|
+
const authorList =
|
|
25
|
+
authors.length > 0 ? h(AuthorList, { names: authors }) : "Unknown";
|
|
26
|
+
|
|
27
|
+
const iconName = expanded ? "chevron-up" : "chevron-down";
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div className="article">
|
|
31
|
+
<div className="article-title">
|
|
32
|
+
<p className="article-author">
|
|
33
|
+
{authorList}, {year.length ? " " + year + ". " : ""}
|
|
34
|
+
</p>
|
|
35
|
+
<a href={data.URL} target="_blank" className="title-link">
|
|
36
|
+
<strong>{data.title}.</strong>
|
|
37
|
+
</a>
|
|
38
|
+
|
|
39
|
+
<span>
|
|
40
|
+
<Button
|
|
41
|
+
onClick={toggleExpand}
|
|
42
|
+
minimal={true}
|
|
43
|
+
rightIcon={iconName}
|
|
44
|
+
className="flat-btn"
|
|
45
|
+
></Button>
|
|
46
|
+
</span>
|
|
47
|
+
</div>
|
|
48
|
+
<Collapse isOpen={expanded}>
|
|
49
|
+
<span className={expanded ? "" : "hidden"}>
|
|
50
|
+
<div className="quotes">
|
|
51
|
+
{data.highlight.map((snippet, si) => {
|
|
52
|
+
let text = snippet;
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<p
|
|
56
|
+
className="gdd-snippet"
|
|
57
|
+
key={si}
|
|
58
|
+
dangerouslySetInnerHTML={{ __html: `...${snippet}...` }}
|
|
59
|
+
></p>
|
|
60
|
+
);
|
|
61
|
+
})}
|
|
62
|
+
</div>
|
|
63
|
+
</span>
|
|
64
|
+
</Collapse>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default Article;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Article from "./Article";
|
|
2
|
+
import { Divider } from "@blueprintjs/core";
|
|
3
|
+
import h from "@macrostrat/hyper";
|
|
4
|
+
import { SubExpansionPanel } from "@macrostrat/map-interface";
|
|
5
|
+
import { XDDSnippet } from "./index";
|
|
6
|
+
|
|
7
|
+
function Journal(props) {
|
|
8
|
+
return h("div.journal", [
|
|
9
|
+
h("div.journal-title", [
|
|
10
|
+
h("h2.journal-title-text", [
|
|
11
|
+
props.data.name,
|
|
12
|
+
h("small.journal-source", [props.data]),
|
|
13
|
+
]),
|
|
14
|
+
]),
|
|
15
|
+
h(Divider),
|
|
16
|
+
props.data.articles.map((article, i) => {
|
|
17
|
+
return h(Article, { key: i, data: article });
|
|
18
|
+
}),
|
|
19
|
+
]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type JournalProps = {
|
|
23
|
+
articles: XDDSnippet[];
|
|
24
|
+
name: string;
|
|
25
|
+
publisher: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Still up for review
|
|
29
|
+
function Journal_(props: JournalProps) {
|
|
30
|
+
const { articles, name, publisher } = props;
|
|
31
|
+
|
|
32
|
+
const helpText = articles[0].pubname;
|
|
33
|
+
|
|
34
|
+
return h(
|
|
35
|
+
SubExpansionPanel,
|
|
36
|
+
{
|
|
37
|
+
title: name,
|
|
38
|
+
helpText: publisher,
|
|
39
|
+
},
|
|
40
|
+
[
|
|
41
|
+
articles.map((article, i) => {
|
|
42
|
+
return h(Article, { key: i, data: article });
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default Journal_;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Spinner } from "@blueprintjs/core";
|
|
2
|
+
import h from "@macrostrat/hyper";
|
|
3
|
+
import Journal from "./Journal";
|
|
4
|
+
import { ExpansionPanel } from "@macrostrat/map-interface";
|
|
5
|
+
|
|
6
|
+
export interface XDDSnippet {
|
|
7
|
+
pubname: string;
|
|
8
|
+
publisher: string;
|
|
9
|
+
_gddid: string;
|
|
10
|
+
title: string;
|
|
11
|
+
doi: string;
|
|
12
|
+
coverDate: string;
|
|
13
|
+
URL: string;
|
|
14
|
+
authors: string;
|
|
15
|
+
hits: number;
|
|
16
|
+
highlight: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function XddExpansion({ xddInfo }) {
|
|
20
|
+
return h(xDDPanelCore, {
|
|
21
|
+
className: "regional-panel",
|
|
22
|
+
data: xddInfo,
|
|
23
|
+
isFetching: xddInfo == undefined || xddInfo.length === 0,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function xDDPanelCore({ isFetching, data: xddInfo, ...rest }) {
|
|
28
|
+
const groupedData = groupSnippetsByJournal(xddInfo);
|
|
29
|
+
|
|
30
|
+
return h(
|
|
31
|
+
ExpansionPanel,
|
|
32
|
+
{
|
|
33
|
+
className: "regional-panel",
|
|
34
|
+
title: "Primary literature",
|
|
35
|
+
helpText: "via xDD",
|
|
36
|
+
...rest,
|
|
37
|
+
},
|
|
38
|
+
[
|
|
39
|
+
h.if(isFetching)(Spinner),
|
|
40
|
+
h.if(!isFetching && xddInfo.length > 0)([
|
|
41
|
+
Array.from(groupedData.entries())?.map(([journal, snippets]) => {
|
|
42
|
+
return h(Journal, {
|
|
43
|
+
name: journal,
|
|
44
|
+
articles: snippets,
|
|
45
|
+
publisher: snippets[0].publisher,
|
|
46
|
+
key: journal,
|
|
47
|
+
});
|
|
48
|
+
}),
|
|
49
|
+
]),
|
|
50
|
+
],
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function groupSnippetsByJournal(
|
|
55
|
+
snippets: XDDSnippet[],
|
|
56
|
+
): Map<string, XDDSnippet[]> {
|
|
57
|
+
const journals = new Map<string, XDDSnippet[]>();
|
|
58
|
+
if (!snippets || snippets.length === 0) {
|
|
59
|
+
return journals;
|
|
60
|
+
}
|
|
61
|
+
for (let snippet of snippets) {
|
|
62
|
+
const { pubname: journal } = snippet;
|
|
63
|
+
if (!journals.has(journal)) {
|
|
64
|
+
journals.set(journal, []);
|
|
65
|
+
}
|
|
66
|
+
journals.get(journal).push(snippet);
|
|
67
|
+
}
|
|
68
|
+
return journals;
|
|
69
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import hyper from "@macrostrat/hyper";
|
|
2
|
+
import styles from "./main.module.styl";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import { Spinner } from "@blueprintjs/core";
|
|
5
|
+
import { useTransition } from "transition-hook";
|
|
6
|
+
|
|
7
|
+
const h = hyper.styled(styles);
|
|
8
|
+
|
|
9
|
+
function LoadingArea(props) {
|
|
10
|
+
const { loaded, children = null, className } = props;
|
|
11
|
+
const trans = useTransition(loaded, 500);
|
|
12
|
+
const invTrans = useTransition(!loaded, 500);
|
|
13
|
+
|
|
14
|
+
return h(
|
|
15
|
+
"div.loading-area",
|
|
16
|
+
{ className: classNames(className, trans.stage) },
|
|
17
|
+
[
|
|
18
|
+
h.if(invTrans.shouldMount)("div.spinner", null, h(Spinner)),
|
|
19
|
+
h.if(trans.shouldMount)("div.data", null, children),
|
|
20
|
+
],
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { LoadingArea };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
transitionable()
|
|
2
|
+
&:global(.enter)
|
|
3
|
+
opacity: 0
|
|
4
|
+
&:global(.enter-active)
|
|
5
|
+
opacity: 1
|
|
6
|
+
transition: opacity 0.5s ease-in-out, height 0.5s ease-in-out, max-height 0.5s ease-in-out
|
|
7
|
+
&:global(.exit)
|
|
8
|
+
opacity: 1
|
|
9
|
+
&:global(.exit-active)
|
|
10
|
+
opacity: 0
|
|
11
|
+
transition: opacity 0.5s ease-in-out, height 0.5s ease-in-out, max-height 0.5s ease-in-out
|
|
12
|
+
transition: height 0.5s ease-in-out, max-height 0.5s ease-in-out
|
|
13
|
+
|
|
14
|
+
.transition-item
|
|
15
|
+
transitionable()
|
|
16
|
+
|
|
17
|
+
.loading-area
|
|
18
|
+
.spinner, .data
|
|
19
|
+
transition: height 0.5s ease-in, opacity 0.2s ease-in
|
|
20
|
+
|
|
21
|
+
.spinner
|
|
22
|
+
position absolute
|
|
23
|
+
top 0
|
|
24
|
+
left 0
|
|
25
|
+
width: 100%
|
|
26
|
+
height 100%
|
|
27
|
+
min-height: 90px
|
|
28
|
+
background-color: var(--panel-background-color)
|
|
29
|
+
padding: 15px
|
|
30
|
+
|
|
31
|
+
&.enter
|
|
32
|
+
.spinner
|
|
33
|
+
height: 0
|
|
34
|
+
opacity: 0
|
|
35
|
+
|
|
36
|
+
.data
|
|
37
|
+
opacity: 1
|
|
38
|
+
|
|
39
|
+
&.from
|
|
40
|
+
.spinner
|
|
41
|
+
height: 90px
|
|
42
|
+
opacity: 1
|
|
43
|
+
|
|
44
|
+
.data
|
|
45
|
+
opacity: 0
|
|
46
|
+
|
|
47
|
+
&.leave
|
|
48
|
+
.spinner
|
|
49
|
+
height: 90px
|
|
50
|
+
opacity: 1
|
|
51
|
+
|
|
52
|
+
.data
|
|
53
|
+
opacity: 0
|
|
54
|
+
|
|
55
|
+
//.transition-item.infodrawer-info
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { format } from "d3-format";
|
|
2
|
+
|
|
3
|
+
export const fmt4 = format(".4~f");
|
|
4
|
+
export const fmt3 = format(".3~f");
|
|
5
|
+
export const fmt2 = format(".2~f");
|
|
6
|
+
export const fmt1 = format(".1~f");
|
|
7
|
+
export const fmtInt = format(".0f");
|
|
8
|
+
|
|
9
|
+
export const addCommas = (x) => {
|
|
10
|
+
x = parseInt(x);
|
|
11
|
+
var parts = x.toString().split(".");
|
|
12
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
13
|
+
return parts.join(".");
|
|
14
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
export function makeOccurrenceTree(data) {
|
|
2
|
+
let occurrenceTree = { phyla: [] };
|
|
3
|
+
let rankMap = {
|
|
4
|
+
25: "unranked",
|
|
5
|
+
23: "kingdom",
|
|
6
|
+
22: "subkingdom",
|
|
7
|
+
21: "superphylum",
|
|
8
|
+
20: "phylum",
|
|
9
|
+
19: "subphylum",
|
|
10
|
+
18: "superclass",
|
|
11
|
+
17: "class",
|
|
12
|
+
16: "subclass",
|
|
13
|
+
15: "infraclass",
|
|
14
|
+
14: "superorder",
|
|
15
|
+
13: "order",
|
|
16
|
+
12: "suborder",
|
|
17
|
+
11: "infraorder",
|
|
18
|
+
10: "superfamily",
|
|
19
|
+
9: "family",
|
|
20
|
+
8: "subfamily",
|
|
21
|
+
7: "tribe",
|
|
22
|
+
6: "subtribe",
|
|
23
|
+
5: "genus",
|
|
24
|
+
4: "subgenus",
|
|
25
|
+
3: "species",
|
|
26
|
+
2: "subspecies",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function getIndex(data, term, property) {
|
|
30
|
+
for (let i = 0, len = data.length; i < len; i++) {
|
|
31
|
+
if (data[i][property] === term) return i;
|
|
32
|
+
}
|
|
33
|
+
return -1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
data.forEach((d) => {
|
|
37
|
+
// Some preprocessing
|
|
38
|
+
d.rank = d.rnk ? rankMap[d.rnk] : d.idr ? rankMap[d.idr] : "Unknown";
|
|
39
|
+
d.italics = d.rnk < 6 ? "italics" : "";
|
|
40
|
+
if (typeof d.tna === "undefined") {
|
|
41
|
+
d.tna = d.idn;
|
|
42
|
+
}
|
|
43
|
+
d.old_name = d.tna.split(" ")[0] != d.idg ? d.tna : "";
|
|
44
|
+
d.url =
|
|
45
|
+
d.rank === "species"
|
|
46
|
+
? d.idg + " " + d.ids
|
|
47
|
+
: d.tid
|
|
48
|
+
? d.tid.split(":")[1] > 0
|
|
49
|
+
? d.idg
|
|
50
|
+
: ""
|
|
51
|
+
: "";
|
|
52
|
+
|
|
53
|
+
// If it has a genus name...
|
|
54
|
+
if (d.idg) {
|
|
55
|
+
let genusRes = d.rsg ? d.rsg + " " : "";
|
|
56
|
+
let speciesRes = d.rss ? " " + d.rss + " " : " ";
|
|
57
|
+
d.genusRes = genusRes;
|
|
58
|
+
// If it's a species...
|
|
59
|
+
if (d.rank === "species") {
|
|
60
|
+
d.display_name1 = d.tna;
|
|
61
|
+
d.display_name2 = d.tna != d.idg + " " + d.ids ? "(" + d.tna + ")" : "";
|
|
62
|
+
d.display_name3 = "";
|
|
63
|
+
} else {
|
|
64
|
+
d.display_name1 = d.idg;
|
|
65
|
+
d.display_name2 = speciesRes;
|
|
66
|
+
d.display_name3 = d.ids;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
d.display_name1 = d.tna;
|
|
70
|
+
d.display_name2 = "";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Find unique phyla
|
|
74
|
+
let phyla = [];
|
|
75
|
+
for (let i = 0; i < occurrenceTree.phyla.length; i++) {
|
|
76
|
+
phyla.push(occurrenceTree.phyla[i].phylum);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (phyla.indexOf(d.phl) < 0) {
|
|
80
|
+
let newPhylum = { phylum: d.phl, classes: [] };
|
|
81
|
+
occurrenceTree.phyla.push(newPhylum);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Find unique phylum/class combinations
|
|
85
|
+
let phyla_classes = [];
|
|
86
|
+
for (let i = 0; i < occurrenceTree.phyla.length; i++) {
|
|
87
|
+
for (let j = 0; j < occurrenceTree.phyla[i].classes.length; j++) {
|
|
88
|
+
phyla_classes.push(
|
|
89
|
+
occurrenceTree.phyla[i].phylum +
|
|
90
|
+
"-" +
|
|
91
|
+
occurrenceTree.phyla[i].classes[j].nameClass,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (phyla_classes.indexOf(d.phl + "-" + d.cll) < 0) {
|
|
97
|
+
let newClass = { nameClass: d.cll, families: [] };
|
|
98
|
+
let phylumIndex = getIndex(occurrenceTree.phyla, d.phl, "phylum");
|
|
99
|
+
occurrenceTree.phyla[phylumIndex]["classes"].push(newClass);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Find unique phylum/class/family combinations
|
|
103
|
+
let phyla_class_family = [];
|
|
104
|
+
for (let i = 0; i < occurrenceTree.phyla.length; i++) {
|
|
105
|
+
for (let j = 0; j < occurrenceTree.phyla[i].classes.length; j++) {
|
|
106
|
+
for (
|
|
107
|
+
let k = 0;
|
|
108
|
+
k < occurrenceTree.phyla[i].classes[j].families.length;
|
|
109
|
+
k++
|
|
110
|
+
) {
|
|
111
|
+
phyla_class_family.push(
|
|
112
|
+
occurrenceTree.phyla[i].phylum +
|
|
113
|
+
"-" +
|
|
114
|
+
occurrenceTree.phyla[i].classes[j].nameClass +
|
|
115
|
+
"-" +
|
|
116
|
+
occurrenceTree.phyla[i].classes[j].families[k].family,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (phyla_class_family.indexOf(d.phl + "-" + d.cll + "-" + d.fml) < 0) {
|
|
123
|
+
let newFamily = { family: d.fml, genera: [] };
|
|
124
|
+
let phylumIndex = getIndex(occurrenceTree.phyla, d.phl, "phylum");
|
|
125
|
+
let classIndex = getIndex(
|
|
126
|
+
occurrenceTree.phyla[phylumIndex].classes,
|
|
127
|
+
d.cll,
|
|
128
|
+
"nameClass",
|
|
129
|
+
);
|
|
130
|
+
occurrenceTree.phyla[phylumIndex].classes[classIndex]["families"].push(
|
|
131
|
+
newFamily,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Place genera into the right phylum/class/family
|
|
136
|
+
let phylumIndex = getIndex(occurrenceTree.phyla, d.phl, "phylum");
|
|
137
|
+
let classIndex = getIndex(
|
|
138
|
+
occurrenceTree.phyla[phylumIndex].classes,
|
|
139
|
+
d.cll,
|
|
140
|
+
"nameClass",
|
|
141
|
+
);
|
|
142
|
+
let familyIndex = getIndex(
|
|
143
|
+
occurrenceTree.phyla[phylumIndex].classes[classIndex].families,
|
|
144
|
+
d.fml,
|
|
145
|
+
"family",
|
|
146
|
+
);
|
|
147
|
+
occurrenceTree.phyla[phylumIndex].classes[classIndex].families[
|
|
148
|
+
familyIndex
|
|
149
|
+
].genera.push(d);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
for (let i = 0; i < occurrenceTree.phyla.length; i++) {
|
|
153
|
+
let undefinedClassIndex;
|
|
154
|
+
for (let j = 0; j < occurrenceTree.phyla[i].classes.length; j++) {
|
|
155
|
+
let undefinedFamilyIndex;
|
|
156
|
+
for (
|
|
157
|
+
let k = 0;
|
|
158
|
+
k < occurrenceTree.phyla[i].classes[j].families.length;
|
|
159
|
+
k++
|
|
160
|
+
) {
|
|
161
|
+
if (
|
|
162
|
+
typeof occurrenceTree.phyla[i].classes[j].families[k].family ===
|
|
163
|
+
"undefined"
|
|
164
|
+
) {
|
|
165
|
+
undefinedFamilyIndex = k;
|
|
166
|
+
occurrenceTree.phyla[i].classes[j].families[k].family =
|
|
167
|
+
"Miscellaneous " +
|
|
168
|
+
(typeof occurrenceTree.phyla[i].classes[j].nameClass ===
|
|
169
|
+
"undefined")
|
|
170
|
+
? "Miscellaneous unranked taxa"
|
|
171
|
+
: occurrenceTree.phyla[i].classes[j].nameClass;
|
|
172
|
+
occurrenceTree.phyla[i].classes[j].families[k].noFamily = true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (typeof undefinedFamilyIndex != "undefined") {
|
|
177
|
+
occurrenceTree.phyla[i].classes[j].families.push(
|
|
178
|
+
occurrenceTree.phyla[i].classes[j].families.splice(
|
|
179
|
+
undefinedFamilyIndex,
|
|
180
|
+
1,
|
|
181
|
+
)[0],
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (typeof occurrenceTree.phyla[i].classes[j].nameClass === "undefined") {
|
|
186
|
+
undefinedFamilyIndex = j;
|
|
187
|
+
occurrenceTree.phyla[i].classes[j].nameClass =
|
|
188
|
+
"Miscellaneous " +
|
|
189
|
+
(typeof occurrenceTree.phyla[i].phylum === "undefined")
|
|
190
|
+
? "Miscellaneous unranked taxa"
|
|
191
|
+
: occurrenceTree.phyla[i].phylum;
|
|
192
|
+
occurrenceTree.phyla[i].classes[j].noClass = true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (typeof undefinedClassIndex != "undefined") {
|
|
197
|
+
occurrenceTree.phyla[i].classes.push(
|
|
198
|
+
occurrenceTree.phyla[i].classes.splice(undefinedClassIndex, 1)[0],
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (typeof occurrenceTree.phyla[i].phylum === "undefined") {
|
|
203
|
+
occurrenceTree.phyla[i].phylum = "Unranked taxa";
|
|
204
|
+
occurrenceTree.phyla[i].unranked = true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return occurrenceTree;
|
|
209
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
export const addCommas = (x) => {
|
|
2
|
+
x = parseInt(x);
|
|
3
|
+
var parts = x.toString().split(".");
|
|
4
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
5
|
+
return parts.join(".");
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const sum = (data, prop) => {
|
|
9
|
+
if (!data || !data.length) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
return data
|
|
13
|
+
.map((d) => {
|
|
14
|
+
return d[prop];
|
|
15
|
+
})
|
|
16
|
+
.reduce((a, b) => {
|
|
17
|
+
return a + b;
|
|
18
|
+
}, 0);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const hexToRgb = (hex, opacity) => {
|
|
22
|
+
if (!hex) {
|
|
23
|
+
return "rgba(0,0,0,0.3)";
|
|
24
|
+
}
|
|
25
|
+
hex = hex.replace("#", "");
|
|
26
|
+
let bigint = parseInt(hex, 16);
|
|
27
|
+
let r = (bigint >> 16) & 255;
|
|
28
|
+
let g = (bigint >> 8) & 255;
|
|
29
|
+
let b = bigint & 255;
|
|
30
|
+
return `rgba(${r},${g},${b},${opacity || 0.8})`;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type TimescaleDivision = {
|
|
34
|
+
name: string;
|
|
35
|
+
abbrev: string;
|
|
36
|
+
t_age: number;
|
|
37
|
+
b_age: number;
|
|
38
|
+
color: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const timescale: TimescaleDivision[] = [
|
|
42
|
+
{ name: "Quaternary", abbrev: "Q", t_age: 0, b_age: 2.588, color: "#F9F97F" },
|
|
43
|
+
{
|
|
44
|
+
name: "Neogene",
|
|
45
|
+
abbrev: "Ng",
|
|
46
|
+
t_age: 2.588,
|
|
47
|
+
b_age: 23.03,
|
|
48
|
+
color: "#FFE619",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "Paleogene",
|
|
52
|
+
abbrev: "Pg",
|
|
53
|
+
t_age: 23.03,
|
|
54
|
+
b_age: 66,
|
|
55
|
+
color: "#FD9A52",
|
|
56
|
+
},
|
|
57
|
+
{ name: "Cretaceous", abbrev: "K", t_age: 66, b_age: 145, color: "#7FC64E" },
|
|
58
|
+
{ name: "Jurassic", abbrev: "J", t_age: 145, b_age: 201.3, color: "#34B2C9" },
|
|
59
|
+
{
|
|
60
|
+
name: "Triassic",
|
|
61
|
+
abbrev: "Tr",
|
|
62
|
+
t_age: 201.3,
|
|
63
|
+
b_age: 252.17,
|
|
64
|
+
color: "#812B92",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "Permian",
|
|
68
|
+
abbrev: "P",
|
|
69
|
+
t_age: 252.17,
|
|
70
|
+
b_age: 298.9,
|
|
71
|
+
color: "#F04028",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "Carboniferous",
|
|
75
|
+
abbrev: "C",
|
|
76
|
+
t_age: 298.9,
|
|
77
|
+
b_age: 358.9,
|
|
78
|
+
color: "#67A599",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "Devonian",
|
|
82
|
+
abbrev: "D",
|
|
83
|
+
t_age: 358.9,
|
|
84
|
+
b_age: 419.2,
|
|
85
|
+
color: "#CB8C37",
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "Silurian",
|
|
89
|
+
abbrev: "S",
|
|
90
|
+
t_age: 419.2,
|
|
91
|
+
b_age: 443.8,
|
|
92
|
+
color: "#B3E1B6",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "Ordovician",
|
|
96
|
+
abbrev: "O",
|
|
97
|
+
t_age: 443.8,
|
|
98
|
+
b_age: 485.4,
|
|
99
|
+
color: "#009270",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "Cambrian",
|
|
103
|
+
abbrev: "Cm",
|
|
104
|
+
t_age: 485.4,
|
|
105
|
+
b_age: 541,
|
|
106
|
+
color: "#7FA056",
|
|
107
|
+
},
|
|
108
|
+
{ name: "Ediacaran", abbrev: "E", t_age: 541, b_age: 635, color: "#FFC3E1" },
|
|
109
|
+
{
|
|
110
|
+
name: "Cryogenian",
|
|
111
|
+
abbrev: "Cr",
|
|
112
|
+
t_age: 635,
|
|
113
|
+
b_age: 720,
|
|
114
|
+
color: "#FFAFD7",
|
|
115
|
+
},
|
|
116
|
+
{ name: "Tonian", abbrev: "T", t_age: 720, b_age: 1000, color: "#FFA5D2" },
|
|
117
|
+
{ name: "Stenian", abbrev: "St", t_age: 1000, b_age: 1200, color: "#FFA5D2" },
|
|
118
|
+
{
|
|
119
|
+
name: "Ectasian",
|
|
120
|
+
abbrev: "Ec",
|
|
121
|
+
t_age: 1200,
|
|
122
|
+
b_age: 1400,
|
|
123
|
+
color: "#FF98CC",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "Calymmian",
|
|
127
|
+
abbrev: "Ca",
|
|
128
|
+
t_age: 1400,
|
|
129
|
+
b_age: 1600,
|
|
130
|
+
color: "#FF8BC5",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "Statherian",
|
|
134
|
+
abbrev: "St",
|
|
135
|
+
t_age: 1600,
|
|
136
|
+
b_age: 1800,
|
|
137
|
+
color: "#EE93C1",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "Orosirian",
|
|
141
|
+
abbrev: "Or",
|
|
142
|
+
t_age: 1800,
|
|
143
|
+
b_age: 2050,
|
|
144
|
+
color: "#E874AF",
|
|
145
|
+
},
|
|
146
|
+
{ name: "Rhyacian", abbrev: "R", t_age: 2050, b_age: 2300, color: "#EB84B8" },
|
|
147
|
+
{
|
|
148
|
+
name: "Siderian",
|
|
149
|
+
abbrev: "Sd",
|
|
150
|
+
t_age: 2300,
|
|
151
|
+
b_age: 2500,
|
|
152
|
+
color: "#E874AF",
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
export * from "./fossils";
|
|
157
|
+
export * from "./formatting";
|