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 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
- ## CSV input
27
+ ## Data Input
28
28
 
29
- The allotaxonometer expects 2 tables in the following form:
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 elem1) {
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 elem2) {
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 elem1) {
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 elem2) {
656
+ for (const item of normalized2) {
642
657
  const existing = typeMap.get(item.types);
643
658
  if (existing) {
644
659
  existing.counts2 = item.counts;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allotaxonometer-ui",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Headless UI components for allotaxonometer visualizations built with Svelte 5",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",