allotaxonometer-ui 0.1.15 → 0.1.16
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/README.md +12 -2
- package/dist/index.js +29 -4
- package/dist/ssr/index.js +17 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,10 +24,20 @@ npm install allotaxonometer-ui
|
|
|
24
24
|
- Explore systems and formulate research questions: we recommend starting with the web app...
|
|
25
25
|
- Running multiple or larger scale analyses: we recommend using the py-allotax, which details its install instructions, details the required data format, and provides examples in its repo.
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Data Input
|
|
28
28
|
|
|
29
|
-
The allotaxonometer expects 2
|
|
29
|
+
The allotaxonometer expects 2 datasets with `types` and `counts`. The `totalunique` and `probs` fields are **optional** and will be calculated automatically if not provided.
|
|
30
30
|
|
|
31
|
+
### Minimal Format (Recommended)
|
|
32
|
+
```javascript
|
|
33
|
+
const data = [{
|
|
34
|
+
types: ['John', 'William', 'James', 'George', 'Charles'],
|
|
35
|
+
counts: [8502, 7494, 5097, 4458, 4061]
|
|
36
|
+
// totalunique and probs calculated automatically!
|
|
37
|
+
}];
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Full Format (All Fields)
|
|
31
41
|
| | types | counts | totalunique | probs |
|
|
32
42
|
|----|---------|----------|---------------|---------|
|
|
33
43
|
| 0 | John | 8502 | 1161 | 0.0766 |
|
package/dist/index.js
CHANGED
|
@@ -1569,14 +1569,39 @@ function zeros(length){
|
|
|
1569
1569
|
return Array.from(empty_mat, arr => arr.fill(0))
|
|
1570
1570
|
}
|
|
1571
1571
|
|
|
1572
|
+
// Normalize a dataset: calculate totalunique and probs if missing
|
|
1573
|
+
function normalizeDataset(data) {
|
|
1574
|
+
// If data already has all required fields, return as-is
|
|
1575
|
+
if (data.every(item => item.probs !== undefined && item.totalunique !== undefined)) {
|
|
1576
|
+
return data;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
// Calculate total count for probability calculation
|
|
1580
|
+
const totalCount = data.reduce((sum, item) => sum + item.counts, 0);
|
|
1581
|
+
const totalunique = data.length;
|
|
1582
|
+
|
|
1583
|
+
// Return normalized data with calculated fields
|
|
1584
|
+
return data.map(item => ({
|
|
1585
|
+
types: item.types,
|
|
1586
|
+
counts: item.counts,
|
|
1587
|
+
totalunique: item.totalunique ?? totalunique,
|
|
1588
|
+
probs: item.probs ?? (item.counts / totalCount)
|
|
1589
|
+
}));
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1572
1592
|
// Optimized combElems - Single-pass approach (Opt2)
|
|
1573
1593
|
// This version shows 20-50% performance improvements in most scenarios
|
|
1594
|
+
// Now supports optional totalunique and probs fields
|
|
1574
1595
|
function combElems(elem1, elem2) {
|
|
1596
|
+
// Normalize datasets: calculate totalunique and probs if missing
|
|
1597
|
+
const normalized1 = normalizeDataset(elem1);
|
|
1598
|
+
const normalized2 = normalizeDataset(elem2);
|
|
1599
|
+
|
|
1575
1600
|
// Build union and collect data in single pass
|
|
1576
1601
|
const typeMap = new Map();
|
|
1577
|
-
|
|
1602
|
+
|
|
1578
1603
|
// Process first dataset
|
|
1579
|
-
for (const item of
|
|
1604
|
+
for (const item of normalized1) {
|
|
1580
1605
|
typeMap.set(item.types, {
|
|
1581
1606
|
counts1: item.counts,
|
|
1582
1607
|
probs1: item.probs,
|
|
@@ -1584,9 +1609,9 @@ function combElems(elem1, elem2) {
|
|
|
1584
1609
|
probs2: 0
|
|
1585
1610
|
});
|
|
1586
1611
|
}
|
|
1587
|
-
|
|
1612
|
+
|
|
1588
1613
|
// Process second dataset, updating existing or adding new
|
|
1589
|
-
for (const item of
|
|
1614
|
+
for (const item of normalized2) {
|
|
1590
1615
|
const existing = typeMap.get(item.types);
|
|
1591
1616
|
if (existing) {
|
|
1592
1617
|
existing.counts2 = item.counts;
|
package/dist/ssr/index.js
CHANGED
|
@@ -628,9 +628,24 @@ function zeros(length) {
|
|
|
628
628
|
let empty_mat = createArray(length, length);
|
|
629
629
|
return Array.from(empty_mat, (arr) => arr.fill(0));
|
|
630
630
|
}
|
|
631
|
+
function normalizeDataset(data) {
|
|
632
|
+
if (data.every((item) => item.probs !== void 0 && item.totalunique !== void 0)) {
|
|
633
|
+
return data;
|
|
634
|
+
}
|
|
635
|
+
const totalCount = data.reduce((sum2, item) => sum2 + item.counts, 0);
|
|
636
|
+
const totalunique = data.length;
|
|
637
|
+
return data.map((item) => ({
|
|
638
|
+
types: item.types,
|
|
639
|
+
counts: item.counts,
|
|
640
|
+
totalunique: item.totalunique ?? totalunique,
|
|
641
|
+
probs: item.probs ?? item.counts / totalCount
|
|
642
|
+
}));
|
|
643
|
+
}
|
|
631
644
|
function combElems(elem1, elem2) {
|
|
645
|
+
const normalized1 = normalizeDataset(elem1);
|
|
646
|
+
const normalized2 = normalizeDataset(elem2);
|
|
632
647
|
const typeMap = /* @__PURE__ */ new Map();
|
|
633
|
-
for (const item of
|
|
648
|
+
for (const item of normalized1) {
|
|
634
649
|
typeMap.set(item.types, {
|
|
635
650
|
counts1: item.counts,
|
|
636
651
|
probs1: item.probs,
|
|
@@ -638,7 +653,7 @@ function combElems(elem1, elem2) {
|
|
|
638
653
|
probs2: 0
|
|
639
654
|
});
|
|
640
655
|
}
|
|
641
|
-
for (const item of
|
|
656
|
+
for (const item of normalized2) {
|
|
642
657
|
const existing = typeMap.get(item.types);
|
|
643
658
|
if (existing) {
|
|
644
659
|
existing.counts2 = item.counts;
|