@ca-plant-list/ca-plant-list 0.4.8 → 0.4.10
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/.github/workflows/main.yml +20 -0
- package/.vscode/settings.json +7 -2
- package/data/glossary/perianth.md +1 -0
- package/data/inattaxonphotos.csv +68 -4
- package/data/taxa.csv +5 -3
- package/data/text/Toxicoscordion-fremontii.md +1 -0
- package/data/text/Toxicoscordion-paniculatum.md +1 -0
- package/data/text/Toxicoscordion-venenosum-var-venenosum.md +1 -0
- package/ebook/css/main.css +9 -1
- package/eslint.config.mjs +9 -9
- package/lib/csv.js +27 -5
- package/lib/ebook/images.js +79 -52
- package/lib/ebook/pages/taxonpage.js +25 -27
- package/lib/ebook/plantbook.js +147 -139
- package/lib/htmltaxon.js +124 -117
- package/lib/inat_photo.js +15 -15
- package/lib/progressmeter.js +29 -0
- package/lib/taxa.js +23 -22
- package/lib/util.js +4 -3
- package/lib/utils/inat-tools.js +90 -0
- package/lib/web/pagetaxon.js +199 -190
- package/package.json +4 -3
- package/scripts/cpl-photos.js +179 -0
- package/tmp/config.json +21 -0
- package/tmp/exceptions.json +93 -0
- package/tmp/families.json +790 -0
- package/tmp/genera.json +5566 -0
- package/tmp/inattaxonphotos.csv +6059 -0
- package/tmp/synonyms.csv +2141 -0
- package/tmp/taxa_include.csv +19 -0
- package/types/classes.d.ts +21 -20
- package/data/photos.csv +0 -9
- package/lib/ebook/taxonimage.js +0 -23
@@ -1,26 +1,25 @@
|
|
1
|
-
import imageSize from "image-size";
|
2
1
|
import { EBookPage } from "../ebookpage.js";
|
3
2
|
import { XHTML } from "../xhtml.js";
|
4
3
|
import { Markdown } from "../../markdown.js";
|
5
4
|
import { HTMLTaxon } from "../../htmltaxon.js";
|
6
5
|
import { Config } from "../../config.js";
|
7
6
|
import { Files } from "../../files.js";
|
7
|
+
import { Images } from "../images.js";
|
8
|
+
import imageSize from "image-size";
|
8
9
|
|
9
10
|
class TaxonPage extends EBookPage {
|
10
|
-
#outputDir;
|
11
11
|
#taxon;
|
12
|
-
#
|
12
|
+
#images;
|
13
13
|
|
14
14
|
/**
|
15
15
|
* @param {string} outputDir
|
16
16
|
* @param {Taxon} taxon
|
17
|
-
* @param {
|
17
|
+
* @param {Images} images
|
18
18
|
*/
|
19
|
-
constructor(outputDir, taxon,
|
19
|
+
constructor(outputDir, taxon, images) {
|
20
20
|
super(outputDir + "/" + taxon.getFileName(), taxon.getName());
|
21
|
-
this.#outputDir = outputDir;
|
22
21
|
this.#taxon = taxon;
|
23
|
-
this.#
|
22
|
+
this.#images = images;
|
24
23
|
}
|
25
24
|
|
26
25
|
renderPageBody() {
|
@@ -45,7 +44,7 @@ class TaxonPage extends EBookPage {
|
|
45
44
|
html += XHTML.wrap(
|
46
45
|
"div",
|
47
46
|
XHTML.getLink(family.getFileName(), family.getName()),
|
48
|
-
{ class: "section" }
|
47
|
+
{ class: "section" },
|
49
48
|
);
|
50
49
|
|
51
50
|
const cn = this.#taxon.getCommonNames();
|
@@ -59,26 +58,25 @@ class TaxonPage extends EBookPage {
|
|
59
58
|
|
60
59
|
html += renderCustomText(this.#taxon.getBaseFileName());
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
}
|
77
|
-
photoHTML += XHTML.wrap("figure", img);
|
78
|
-
}
|
79
|
-
if (photoHTML) {
|
80
|
-
html += XHTML.wrap("div", photoHTML);
|
61
|
+
const photos = Images.getTaxonPhotos(this.#taxon);
|
62
|
+
|
63
|
+
let photoHTML = "";
|
64
|
+
for (const photo of photos) {
|
65
|
+
const dimensions = imageSize.imageSize(
|
66
|
+
this.#images.getCompressedFilePath(photo),
|
67
|
+
);
|
68
|
+
let img = XHTML.textElement("img", "", {
|
69
|
+
src: `i/${this.#images.getCompressedImageName(photo)}`,
|
70
|
+
style: "max-width:" + dimensions.width + "px",
|
71
|
+
});
|
72
|
+
const caption = `${photo.rights === "CC0" ? "By" : "(c)"} ${photo.rightsHolder} ${photo.rights && `(${photo.rights})`}`;
|
73
|
+
if (caption) {
|
74
|
+
img += XHTML.textElement("figcaption", caption);
|
81
75
|
}
|
76
|
+
photoHTML += XHTML.wrap("figure", img);
|
77
|
+
}
|
78
|
+
if (photoHTML) {
|
79
|
+
html += XHTML.wrap("div", photoHTML, "photos");
|
82
80
|
}
|
83
81
|
|
84
82
|
return html;
|
package/lib/ebook/plantbook.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { ProgressMeter } from "../progressmeter.js";
|
1
2
|
import { EBook } from "./ebook.js";
|
2
3
|
import { EBookSiteGenerator } from "./ebooksitegenerator.js";
|
3
4
|
import { GlossaryPages } from "./glossarypages.js";
|
@@ -10,153 +11,160 @@ import { TaxonPage } from "./pages/taxonpage.js";
|
|
10
11
|
import { TOCPage } from "./pages/tocpage.js";
|
11
12
|
|
12
13
|
class PlantBook extends EBook {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
}
|
35
|
-
|
36
|
-
async createPages() {
|
37
|
-
const contentDir = this.getContentDir();
|
38
|
-
|
39
|
-
await this.#images.createImages();
|
40
|
-
|
41
|
-
console.log("creating taxon pages");
|
42
|
-
const taxonList = this.#taxa.getTaxonList();
|
43
|
-
for (const taxon of taxonList) {
|
44
|
-
const name = taxon.getName();
|
45
|
-
new TaxonPage(
|
46
|
-
contentDir,
|
47
|
-
taxon,
|
48
|
-
this.#images.getTaxonImages(name)
|
49
|
-
).create();
|
14
|
+
#taxa;
|
15
|
+
#glossary;
|
16
|
+
#images;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @param {string} outputDir
|
20
|
+
* @param {Config} config
|
21
|
+
* @param {Taxa} taxa
|
22
|
+
*/
|
23
|
+
constructor(outputDir, config, taxa) {
|
24
|
+
super(
|
25
|
+
outputDir,
|
26
|
+
getRequiredConfigValue(config, "filename"),
|
27
|
+
getRequiredConfigValue(config, "pub_id"),
|
28
|
+
getRequiredConfigValue(config, "title"),
|
29
|
+
);
|
30
|
+
|
31
|
+
this.#taxa = taxa;
|
32
|
+
const generator = new EBookSiteGenerator(this.getContentDir());
|
33
|
+
this.#glossary = new GlossaryPages(generator);
|
34
|
+
this.#images = new Images(generator, this.getContentDir(), taxa);
|
50
35
|
}
|
51
36
|
|
52
|
-
|
53
|
-
|
54
|
-
|
37
|
+
async createPages() {
|
38
|
+
const contentDir = this.getContentDir();
|
39
|
+
|
40
|
+
const taxonList = this.#taxa.getTaxonList();
|
41
|
+
|
42
|
+
await this.#images.createImages(taxonList);
|
43
|
+
|
44
|
+
const meter = new ProgressMeter(
|
45
|
+
"creating taxon pages",
|
46
|
+
taxonList.length,
|
47
|
+
);
|
48
|
+
for (let index = 0; index < taxonList.length; index++) {
|
49
|
+
const taxon = taxonList[index];
|
50
|
+
new TaxonPage(contentDir, taxon, this.#images).create();
|
51
|
+
meter.update(index + 1);
|
52
|
+
}
|
53
|
+
meter.stop();
|
54
|
+
|
55
|
+
// Create lists.
|
56
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
57
|
+
new PageListFlowerColor(contentDir, color).create();
|
58
|
+
}
|
59
|
+
|
60
|
+
PageListFlowers.createPages(contentDir, this.#taxa);
|
61
|
+
|
62
|
+
new PageListFamilies(contentDir, this.#taxa.getFamilies()).create();
|
63
|
+
for (const family of this.#taxa.getFamilies().getFamilies()) {
|
64
|
+
const taxa = family.getTaxa();
|
65
|
+
if (!taxa) {
|
66
|
+
continue;
|
67
|
+
}
|
68
|
+
const name = family.getName();
|
69
|
+
new PageListSpecies(
|
70
|
+
contentDir,
|
71
|
+
taxa,
|
72
|
+
name + ".html",
|
73
|
+
name,
|
74
|
+
).create();
|
75
|
+
}
|
76
|
+
new PageListSpecies(
|
77
|
+
contentDir,
|
78
|
+
taxonList,
|
79
|
+
"list_species.html",
|
80
|
+
"All Species",
|
81
|
+
).create();
|
82
|
+
|
83
|
+
this.#glossary.renderPages();
|
84
|
+
|
85
|
+
new TOCPage(contentDir, this.#taxa).create();
|
55
86
|
}
|
56
87
|
|
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
|
-
|
88
|
+
renderManifestEntries() {
|
89
|
+
let xml = "";
|
90
|
+
|
91
|
+
// Add lists.
|
92
|
+
xml +=
|
93
|
+
'<item id="lspecies" href="list_species.html" media-type="application/xhtml+xml" />';
|
94
|
+
xml +=
|
95
|
+
'<item id="lfamilies" href="list_families.html" media-type="application/xhtml+xml" />';
|
96
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
97
|
+
xml +=
|
98
|
+
'<item id="l' +
|
99
|
+
color.getColorName() +
|
100
|
+
'" href="' +
|
101
|
+
color.getFileName() +
|
102
|
+
'" media-type="application/xhtml+xml" />';
|
103
|
+
}
|
104
|
+
|
105
|
+
// Add family pages.
|
106
|
+
for (const family of this.#taxa.getFamilies().getFamilies()) {
|
107
|
+
const taxa = family.getTaxa();
|
108
|
+
if (!taxa) {
|
109
|
+
continue;
|
110
|
+
}
|
111
|
+
xml +=
|
112
|
+
'<item id="fam' +
|
113
|
+
family.getName() +
|
114
|
+
'" href="' +
|
115
|
+
family.getFileName() +
|
116
|
+
'" media-type="application/xhtml+xml" />';
|
117
|
+
}
|
118
|
+
|
119
|
+
// Add taxon pages.
|
120
|
+
const taxa = this.#taxa.getTaxonList();
|
121
|
+
for (let index = 0; index < taxa.length; index++) {
|
122
|
+
const taxon = taxa[index];
|
123
|
+
xml +=
|
124
|
+
'<item id="t' +
|
125
|
+
index +
|
126
|
+
'" href="' +
|
127
|
+
taxon.getFileName() +
|
128
|
+
'" media-type="application/xhtml+xml" />';
|
129
|
+
}
|
130
|
+
|
131
|
+
xml += PageListFlowers.getManifestEntries();
|
132
|
+
xml += this.#glossary.getManifestEntries();
|
133
|
+
xml += this.#images.getManifestEntries();
|
134
|
+
|
135
|
+
return xml;
|
95
136
|
}
|
96
137
|
|
97
|
-
|
98
|
-
|
99
|
-
const taxa = family.getTaxa();
|
100
|
-
if (!taxa) {
|
101
|
-
continue;
|
102
|
-
}
|
103
|
-
xml +=
|
104
|
-
'<item id="fam' +
|
105
|
-
family.getName() +
|
106
|
-
'" href="' +
|
107
|
-
family.getFileName() +
|
108
|
-
'" media-type="application/xhtml+xml" />';
|
109
|
-
}
|
138
|
+
renderSpineElements() {
|
139
|
+
let xml = "";
|
110
140
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
'<item id="t' +
|
117
|
-
index +
|
118
|
-
'" href="' +
|
119
|
-
taxon.getFileName() +
|
120
|
-
'" media-type="application/xhtml+xml" />';
|
121
|
-
}
|
141
|
+
// Add lists.
|
142
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
143
|
+
xml += '<itemref idref="l' + color.getColorName() + '"/>';
|
144
|
+
}
|
145
|
+
xml += PageListFlowers.getSpineEntries();
|
122
146
|
|
123
|
-
|
124
|
-
|
125
|
-
xml += this.#images.getManifestEntries();
|
147
|
+
xml += '<itemref idref="lfamilies"/>';
|
148
|
+
xml += '<itemref idref="lspecies"/>';
|
126
149
|
|
127
|
-
|
128
|
-
|
150
|
+
// Add families.
|
151
|
+
for (const family of this.#taxa.getFamilies().getFamilies()) {
|
152
|
+
const taxa = family.getTaxa();
|
153
|
+
if (!taxa) {
|
154
|
+
continue;
|
155
|
+
}
|
156
|
+
xml += '<itemref idref="fam' + family.getName() + '"/>';
|
157
|
+
}
|
129
158
|
|
130
|
-
|
131
|
-
|
159
|
+
// Add taxa.
|
160
|
+
for (let index = 0; index < this.#taxa.getTaxonList().length; index++) {
|
161
|
+
xml += '<itemref idref="t' + index + '"/>';
|
162
|
+
}
|
132
163
|
|
133
|
-
|
134
|
-
for (const color of this.#taxa.getFlowerColors()) {
|
135
|
-
xml += '<itemref idref="l' + color.getColorName() + '"/>';
|
136
|
-
}
|
137
|
-
xml += PageListFlowers.getSpineEntries();
|
138
|
-
|
139
|
-
xml += '<itemref idref="lfamilies"/>';
|
140
|
-
xml += '<itemref idref="lspecies"/>';
|
141
|
-
|
142
|
-
// Add families.
|
143
|
-
for (const family of this.#taxa.getFamilies().getFamilies()) {
|
144
|
-
const taxa = family.getTaxa();
|
145
|
-
if (!taxa) {
|
146
|
-
continue;
|
147
|
-
}
|
148
|
-
xml += '<itemref idref="fam' + family.getName() + '"/>';
|
149
|
-
}
|
164
|
+
xml += this.#glossary.getSpineEntries();
|
150
165
|
|
151
|
-
|
152
|
-
for (let index = 0; index < this.#taxa.getTaxonList().length; index++) {
|
153
|
-
xml += '<itemref idref="t' + index + '"/>';
|
166
|
+
return xml;
|
154
167
|
}
|
155
|
-
|
156
|
-
xml += this.#glossary.getSpineEntries();
|
157
|
-
|
158
|
-
return xml;
|
159
|
-
}
|
160
168
|
}
|
161
169
|
|
162
170
|
/**
|
@@ -165,11 +173,11 @@ class PlantBook extends EBook {
|
|
165
173
|
* @returns {string}
|
166
174
|
*/
|
167
175
|
function getRequiredConfigValue(config, name) {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
176
|
+
const value = config.getConfigValue("ebook", name);
|
177
|
+
if (value === undefined) {
|
178
|
+
throw new Error(`Failed to find ebook config for ${name}`);
|
179
|
+
}
|
180
|
+
return value;
|
173
181
|
}
|
174
182
|
|
175
183
|
export { PlantBook };
|
package/lib/htmltaxon.js
CHANGED
@@ -7,141 +7,148 @@ import { TextUtils } from "./textutils.js";
|
|
7
7
|
* @type {Record<string,{title:string,data:function (Taxon):string}>}
|
8
8
|
*/
|
9
9
|
const TAXA_LIST_COLS = {
|
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
|
-
|
10
|
+
CESA: {
|
11
|
+
title: "California",
|
12
|
+
data: (t) => RarePlants.getCESADescription(t.getCESA()),
|
13
|
+
},
|
14
|
+
COMMON_NAME: {
|
15
|
+
title: "Common Name",
|
16
|
+
data: (t) => t.getCommonNames().join(", "),
|
17
|
+
},
|
18
|
+
CNPS_RANK: {
|
19
|
+
title: "CNPS Rank",
|
20
|
+
data: (t) =>
|
21
|
+
HTML.getToolTip(
|
22
|
+
HTML.textElement("span", t.getRPIRankAndThreat()),
|
23
|
+
t.getRPIRankAndThreatTooltip(),
|
24
|
+
),
|
25
|
+
},
|
26
|
+
FESA: {
|
27
|
+
title: "Federal",
|
28
|
+
data: (t) => RarePlants.getFESADescription(t.getFESA()),
|
29
|
+
},
|
30
|
+
SPECIES: {
|
31
|
+
title: "Species",
|
32
|
+
data: (t) => t.getHTMLLink(true, true),
|
33
|
+
},
|
34
|
+
SPECIES_BARE: {
|
35
|
+
title: "Species",
|
36
|
+
data: (t) => t.getHTMLLink(true, false),
|
37
|
+
},
|
38
38
|
};
|
39
39
|
|
40
40
|
const DEFAULT_TAXA_COLUMNS = [
|
41
|
-
|
42
|
-
|
41
|
+
TAXA_LIST_COLS.SPECIES,
|
42
|
+
TAXA_LIST_COLS.COMMON_NAME,
|
43
43
|
];
|
44
44
|
|
45
45
|
class HTMLTaxon {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
46
|
+
/**
|
47
|
+
* @param {string[]|undefined} colors
|
48
|
+
*/
|
49
|
+
static getFlowerColors(colors, includeColorLink = true) {
|
50
|
+
let html = "";
|
51
|
+
if (colors) {
|
52
|
+
for (const color of colors) {
|
53
|
+
const img = HTML.textElement("img", "", {
|
54
|
+
src: "./i/f-" + color + ".svg",
|
55
|
+
alt: color + " flowers",
|
56
|
+
title: color,
|
57
|
+
class: "flr-color",
|
58
|
+
});
|
59
|
+
if (includeColorLink) {
|
60
|
+
html += HTML.wrap("a", img, {
|
61
|
+
href: "./list_fc_" + color + ".html",
|
62
|
+
});
|
63
|
+
} else {
|
64
|
+
html += img;
|
65
|
+
}
|
66
|
+
}
|
65
67
|
}
|
66
|
-
|
68
|
+
return html;
|
67
69
|
}
|
68
|
-
return html;
|
69
|
-
}
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
71
|
+
/**
|
72
|
+
* @param {Taxon} taxon
|
73
|
+
* @param {string} classNames
|
74
|
+
* @param {boolean} [includeColorLink=true]
|
75
|
+
*/
|
76
|
+
static getFlowerInfo(
|
77
|
+
taxon,
|
78
|
+
classNames = "section",
|
79
|
+
includeColorLink = true,
|
80
|
+
) {
|
81
|
+
const lifeCycle = taxon.getLifeCycle();
|
82
|
+
const colors = taxon.getFlowerColors();
|
83
|
+
const monthStart = taxon.getBloomStart();
|
84
|
+
const monthEnd = taxon.getBloomEnd();
|
81
85
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
+
const parts = [];
|
87
|
+
if (lifeCycle) {
|
88
|
+
const text =
|
89
|
+
HTML.wrap("span", TextUtils.ucFirst(lifeCycle), "lc") + ".";
|
90
|
+
parts.push(HTML.wrap("span", text, "lcs"));
|
91
|
+
}
|
92
|
+
|
93
|
+
if (colors || monthStart) {
|
94
|
+
let html = "Flowers: ";
|
95
|
+
html += this.getFlowerColors(colors, includeColorLink);
|
96
|
+
if (monthStart && monthEnd) {
|
97
|
+
html += HTML.wrap(
|
98
|
+
"span",
|
99
|
+
DateUtils.getMonthName(monthStart) +
|
100
|
+
"-" +
|
101
|
+
DateUtils.getMonthName(monthEnd),
|
102
|
+
{ class: "flr-time" },
|
103
|
+
);
|
104
|
+
}
|
105
|
+
parts.push(HTML.wrap("span", html));
|
106
|
+
}
|
107
|
+
return parts.length === 0
|
108
|
+
? ""
|
109
|
+
: HTML.wrap("div", parts.join(""), { class: classNames });
|
86
110
|
}
|
87
111
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
"-" +
|
96
|
-
DateUtils.getMonthName(monthEnd),
|
97
|
-
{ class: "flr-time" }
|
112
|
+
/**
|
113
|
+
* @param {Taxon} taxon
|
114
|
+
*/
|
115
|
+
static getLink(taxon) {
|
116
|
+
return (
|
117
|
+
HTML.getLink(taxon.getFileName(), taxon.getName()) +
|
118
|
+
this.getFlowerColors(taxon.getFlowerColors())
|
98
119
|
);
|
99
|
-
}
|
100
|
-
parts.push(HTML.wrap("span", html));
|
101
120
|
}
|
102
|
-
return HTML.wrap("div", parts.join(""), { class: classNames });
|
103
|
-
}
|
104
121
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
*/
|
119
|
-
static getTaxaTable(taxa, columns = DEFAULT_TAXA_COLUMNS) {
|
120
|
-
let html = "<table><thead>";
|
121
|
-
for (const col of columns) {
|
122
|
-
const className = col.class;
|
123
|
-
const atts = className !== undefined ? className : {};
|
124
|
-
html += HTML.textElement("th", col.title, atts);
|
125
|
-
}
|
126
|
-
html += "</thead>";
|
127
|
-
html += "<tbody>";
|
122
|
+
/**
|
123
|
+
* @param {Taxon[]} taxa
|
124
|
+
* @param {TaxaCol[]} [columns]
|
125
|
+
*/
|
126
|
+
static getTaxaTable(taxa, columns = DEFAULT_TAXA_COLUMNS) {
|
127
|
+
let html = "<table><thead>";
|
128
|
+
for (const col of columns) {
|
129
|
+
const className = col.class;
|
130
|
+
const atts = className !== undefined ? className : {};
|
131
|
+
html += HTML.textElement("th", col.title, atts);
|
132
|
+
}
|
133
|
+
html += "</thead>";
|
134
|
+
html += "<tbody>";
|
128
135
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
for (const taxon of taxa) {
|
137
|
+
html += "<tr>";
|
138
|
+
for (const col of columns) {
|
139
|
+
const data = col.data(taxon);
|
140
|
+
const className = col.class;
|
141
|
+
const atts = className !== undefined ? className : {};
|
142
|
+
html += HTML.wrap("td", data, atts);
|
143
|
+
}
|
144
|
+
html += "</tr>";
|
145
|
+
}
|
139
146
|
|
140
|
-
|
141
|
-
|
147
|
+
html += "</tbody>";
|
148
|
+
html += "</table>";
|
142
149
|
|
143
|
-
|
144
|
-
|
150
|
+
return html;
|
151
|
+
}
|
145
152
|
}
|
146
153
|
|
147
154
|
export { HTMLTaxon, TAXA_LIST_COLS };
|