1.0.10 • Published 4 months ago

chrono-phylo-tree v1.0.10

Weekly downloads
-
License
-
Repository
github
Last release
4 months ago

chrono-phylo-tree Documentation

Overview

The chrono-phylo-tree is a JavaScript/TypeScript library designed to visualize and manage phylogenetic trees. Phylogenetic trees are diagrams that represent evolutionary relationships among species, where each node represents a species, and branches represent the evolutionary lineage, it can also be used in speculative evolution projects.

This documentation provides a detailed explanation of the core components and classes used in the application, including the Species class, which represents individual species in the tree, and the PhTree and Menu components, which handle the visualization and user interaction with the tree.

Try It Out

You can test and explore the functionality of the chrono-phylo-tree library by visiting the following page. This interactive demo allows you to experiment with the library's features, visualize phylogenetic trees, and see how the components work in real-time.

Updates

1.0.9

  • Translation to German thanks to u/Kneeerg

  • PhTree allows to execute functions when the mouse is over the buttons

1.0.8

  • Species class' step functions can include or not species whose display is false.

1.0.7

  • The default duration of the ancestors and descendants are the duration of the species
  • MultiplePhTrees component allows to show the phylogenetic tree from multiple common ancestors

1.0.5

  • PhTree's lines' width can depend or not on the species' duration
  • It's possible to know the steps until a species
  • It's possible to count the maximum steps until the last descendant of a species

1.0.2

  • The duration of the species must be greater than 0
  • Menu doesn't close when a function throws error

Key Features

  • Species Management: The Species class allows you to define species, manage their ancestors and descendants, and calculate properties such as extinction time and duration.
  • Interactive Tree Visualization: The PhTree component renders the phylogenetic tree as an SVG, allowing users to interact with the tree by toggling the visibility of species and accessing detailed information.
  • User-Friendly Interface: The Menu component provides a modal interface for editing species attributes, adding new descendants or ancestors, and deleting species.
  • Localization Support: The application supports multiple languages, making it accessible to a global audience.

How It Works

  1. Species Representation: Each species is represented by an instance of the Species class, which stores its name, appearance time, duration, ancestor, descendants, and other attributes.
  2. Tree Rendering: The PhTree component takes a common ancestor species as input and recursively renders the tree structure using SVG elements. It supports dynamic resizing, padding, and customizable stroke colors.
  3. User Interaction: Users can interact with the tree by clicking on species nodes to open the Menu component, where they can edit species data, add new species, or delete existing ones.
  4. Data Persistence: The application allows users to save the phylogenetic tree as a JSON file, ensuring that the data can be easily stored and reloaded.

This documentation will guide you through the properties, methods, and usage of each component, helping you understand how to build, modify, and interact with phylogenetic trees using this application.

Installation

You can install chrono-phylo-tree via npm:

npm install chrono-phylo-tree

or using yarn:

yarn add chrono-phylo-tree

Usage

Importing the Library

In a JavaScript or TypeScript project, import the necessary modules:

import { Species, PhTree } from "chrono-phylo-tree";

Creating a Phylogenetic Tree

You can create species and construct a phylogenetic tree as follows:

const root = new Species("Hominoidea", -25e6, 6e6);
root.addDescendant("Hilobates", 6e6, 19e6);
const child0 = root.addDescendant("Hominidae", 6e6, 6e6);
child0.addDescendant("Pongo", 6e6, 13e6);
const child1 = child0.addDescendant("Homininae", 6e6, 5e6);
child1.addDescendant("Gorilla", 5e6, 8e6);
const child2 = child1.addDescendant("Hominini", 5e6, 2e6);
const child3 = child2.addDescendant("Pan", 2e6, 3e6);
child3.addDescendant("Pan Troglodytes", 3e6, 3e6);
child3.addDescendant("Pan Paniscus", 3e6, 3e6);
child2.addDescendant("Homo", 2e6, 6e6);

Rendering the Tree in a React Component

If using chrono-phylo-tree in a React project, you can render the tree as follows:

import React from "react";
import { Species, PhTree } from "chrono-phylo-tree";

const root = new Species("Hominoidea", -25e6, 6e6);
root.addDescendant("Hilobates", 6e6, 19e6);
const child0 = root.addDescendant("Hominidae", 6e6, 6e6);
child0.addDescendant("Pongo", 6e6, 13e6);
const child1 = child0.addDescendant("Homininae", 6e6, 5e6);
child1.addDescendant("Gorilla", 5e6, 8e6);
const child2 = child1.addDescendant("Hominini", 5e6, 2e6);
const child3 = child2.addDescendant("Pan", 2e6, 3e6);
child3.addDescendant("Pan Troglodytes", 3e6, 3e6);
child3.addDescendant("Pan Paniscus", 3e6, 3e6);
child2.addDescendant("Homo", 2e6, 6e6);

const App = () => {
  return (
    <PhTree
      commonAncestor={ancestor}
      width={1000}
      height={500}
      stroke="black"
    />
  );
};

export default App;

Species Class

The Species class represents a species in a phylogenetic tree, with properties and methods to manage its ancestors, descendants, and other attributes.

Properties

  • name: stringThe name of the species.
  • apparition: numberThe time at which the species appears in the timeline.
  • duration: numberThe duration for which the species exists.
  • ancestor: Species | undefinedThe ancestor species from which this species descends. It is undefined if this species has no ancestor.
  • descendants: Species[]An array of species that descend from this species.
  • description: string | undefinedAn optional description of the species.
  • display: boolean A flag indicating whether the species should be displayed. Default is true

Methods

Constructor

constructor(
  name = '',
  apparition = 0,
  duration = 0,
  ancestor?: Species,
  descendants: Species[] = [],
  description: string | undefined = undefined
)

Initializes a new instance of the Species class.

  • name: The name of the species.
  • apparition: The time at which the species appears.
  • duration: The duration for which the species exists.
  • ancestor: The ancestor of the species.
  • descendants: An array of descendant species.
  • description: An optional description of the species.

copy

copy(): Species

Creates a deep copy of the current species and its descendants.

addDescendant

addDescendant(
  name = '',
  afterApparition = 0,
  duration = 0,
  description: string | undefined = undefined,
  copy = false
): Species

Adds a descendant to the current species.

  • name: The name of the descendant.
  • afterApparition: The time after the ancestor's appearance when the descendant appears.
  • duration: The duration for which the descendant exists.
  • description: An optional description of the descendant.
  • copy: If true, the current species is copied before adding the descendant.

removeDescendant

removeDescendant(desc: Species): void

Removes a descendant from the current species.

  • desc: The descendant species to remove.

addAncestor

addAncestor(
  name = '',
  previousApparition = 0,
  duration = 0,
  description: string | undefined = undefined,
  display = true,
  copy = false
): Species

Adds an ancestor to the current species.

  • name: The name of the ancestor.
  • previousApparition: The time before the current species' appearance when the ancestor appears.
  • duration: The duration for which the ancestor exists.
  • description: An optional description of the ancestor.
  • display: A flag indicating whether the ancestor should be displayed.
  • copy: If true, the current species is copied before adding the ancestor.

extinction

extinction(): number

Returns the time at which the species goes extinct.

absoluteExtinction

absoluteExtinction(): number

Returns the time at which the species goes extinct, considering its descendants.

absoluteDuration

absoluteDuration(): number

Returns the duration of the species, considering its descendants.

firstAncestor

firstAncestor(includeNotDisplay = false): Species

Returns the first ancestor of the species.

  • includeNotDisplay: If true, includes ancestors that are not displayed.

cousinsExtinction

cousinsExtinction(): number

Returns the extinction time of the species' cousins.

allDescendants

allDescendants(): Species[]

Returns an array of all descendants of the species, sorted by appearance time.

stepsChain

stepsChain(desc: Species, includeNotDisplay = false): Species[]

Returns an array of Species objects representing the chain of species from the current species (this) to the specified descendant (desc). The chain includes all intermediate species in the lineage. If the specified descendant is not a descendant of the current species, the method returns an empty array.

  • desc: The descendant species to which the chain is traced.

  • includeNotDisplay: If true, include the species whose display is false.

stepsUntil

stepsUntil(desc: Species, includeNotDisplay = false): number

Returns the number of steps (generations) from the current species (this) to the specified descendant (desc). If the specified descendant is not a descendant of the current species, the method returns undefined.

  • desc: The descendant species to which the number of steps is calculated.

  • includeNotDisplay: If true, include the species whose display is false.

stepsUntilLastDescendant

stepsUntilLastDescendant(includeNotDisplay = false): number

Returns the maximum number of steps (generations) from the current species (this) to its most distant descendant. If the current species has no descendants, the method returns 0.

  • includeNotDisplay: If true, include the species whose display is false.

toJSON

toJSON(): any

Converts the species and its descendants to a JSON object.

saveJSON

saveJSON(filename: string | undefined = undefined): Promise<void>

Saves the species and its descendants as a JSON file.

  • filename: The name of the file to save. If not provided, the species name is used.

fromJSON

static fromJSON(json: any, ancestor?: Species): Species

Creates a species instance from a JSON object.

  • json: The JSON object representing the species. The structure of the JSON object should follow the format below:
    • name: (string) The name of the species.
    • apparition: (number, optional) The time when the species first appeared. This is only required if the species has no ancestor.
    • afterApparition: (number, optional) The time after the ancestor's apparition when this species appeared. This is required if the species has an ancestor.
    • duration: (number) The duration for which the species existed.
    • description: (string, optional) A description of the species.
    • descendants: (array, optional) An array of JSON objects representing the descendant species. Each descendant follows the same structure as described here.
  • ancestor: (Species, optional) The ancestor species, if any. This is used to calculate the apparition time of the current species based on the ancestor's apparition time.

Example JSON Structure

Here is an example of a JSON object representing a species and its descendants:

{
  "name": "Hominoidea",
  "apparition": -25000000,
  "duration": 6000000,
  "descendants": [
    {
      "name": "Hilobates",
      "afterApparition": 6000000,
      "duration": 19000000
    },
    {
      "name": "Hominidae",
      "afterApparition": 6000000,
      "duration": 6000000,
      "descendants": [
        {
          "name": "Pongo",
          "afterApparition": 6000000,
          "duration": 13000000
        },
        {
          "name": "Homininae",
          "afterApparition": 6000000,
          "duration": 5000000,
          "descendants": [
            {
              "name": "Gorilla",
              "afterApparition": 5000000,
              "duration": 8000000
            },
            {
              "name": "Hominini",
              "afterApparition": 5000000,
              "duration": 2000000,
              "descendants": [
                {
                  "name": "Pan",
                  "afterApparition": 2000000,
                  "duration": 3000000,
                  "descendants": [
                    {
                      "name": "Pan Troglodytes",
                      "afterApparition": 3000000,
                      "duration": 3000000
                    },
                    {
                      "name": "Pan Paniscus",
                      "afterApparition": 3000000,
                      "duration": 3000000
                    }
                  ]
                },
                {
                  "name": "Homo",
                  "afterApparition": 2000000,
                  "duration": 6000000
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

In this example:

  • The root species is "Hominoidea", which appeared 25 million years ago and existed for 6 million years.

  • It has two descendants: "Hilobates" and "Hominidae".

  • "Hominidae" further has descendants like "Pongo" and "Homininae", and so on.

This structure allows for a hierarchical representation of species and their evolutionary relationships.

PhTree Component

The PhTree component is a React-based visualization tool designed to display phylogenetic trees. It allows users to interact with the tree, toggle the visibility of descendants, and access detailed information about each species through a menu.

Features

  • Interactive Tree Visualization: Displays a phylogenetic tree with interactive nodes representing species.
  • Toggle Descendants: Users can show or hide the descendants of any species in the tree.
  • Species Information: Clicking on a species node opens a menu with detailed information and options to modify the species.
  • Customizable Appearance: Supports customization of tree dimensions, padding, stroke color, and number formatting.
  • Time-Based Filtering: Optionally filters the displayed species based on a specified present time.

Properties

The PhTree component accepts the following props:

  • commonAncestor: SpeciesThe root species of the phylogenetic tree.
  • width: number (optional, default: 1000)The width of the SVG canvas.
  • height: number (optional, default: 50)The height per descendant of the SVG canvas.
  • padding: number (optional, default: 0)The padding around the tree.
  • stroke: string (optional, default: "grey")The stroke color for the tree lines.
  • format: (n: number) => string (optional, default: (n) => n.toString())A function to format the display of time values.
  • chronoScale: boolean (optional, default: true)If true, the width of the lines depend on the durection of the species.
  • handleMouseMove: (x: number, y: number) => void (optional)a function that depends on the mouse position.
  • presentTime: number (optional)The current time to highlight in the tree.
  • children:(species: Species | undefined, showMenu: boolean, toggleShowMenu: (species: Species) => void, hoverSpecies: Species | undefined) => React.ReactNode (optional) Render prop to customize the menu content.

State

  • showMenu: booleanControls the visibility of the Menu component.
  • species: Species | undefinedThe currently selected species for which the menu is displayed.
  • showDesc: Map<Species, boolean>A map to track the visibility of descendants for each species.

Methods

  • toggleShowMenu: (species: Species) => voidToggles the visibility of the menu for a given species.
  • toggleShowDesc: (species: Species) => voidToggles the visibility of descendants for a given species, if false, its descendants won't be displayed and the line will extend until its absoluteExtinction().
  • hoverShowMenu: (sp: Species | undefined) => voidToggles the visibility of info about the species

Rendering

The component renders an SVG element that contains the phylogenetic tree. It uses the DrawTree component to recursively draw the tree structure. The children render prop is conditionally rendered based on the showMenu state.

Customization

The PhTree component can be customized using the various props it accepts. Additionally, the children render prop allows for further customization of the menu content displayed when a species node is clicked.

MultiplePhTrees Component

The MultiplePhTrees component is a React-based visualization tool designed to display multiple phylogenetic trees from a list of species. It allows users to visualize and interact with multiple trees simultaneously, providing a comprehensive view of evolutionary relationships among different species.

Features

  • Multiple Tree Visualization: Displays multiple phylogenetic trees based on a list of species, each with its own evolutionary lineage.

  • Common Ancestor Management: Automatically creates a common ancestor for the provided species list, ensuring a unified visualization.

  • Customizable Appearance: Supports customization of tree dimensions, padding, stroke color, and number formatting.

  • Interactive Tree Visualization: Users can interact with the trees by toggling the visibility of species and accessing detailed information through a menu.

Properties

The MultiplePhTrees component accepts the following props:

  • speciesList: Species[] - An array of species that will be used to generate the phylogenetic trees.

  • width: number (optional, default: 1000) - The width of the SVG canvas.

  • height: number (optional, default: 50) - The height per descendant of the SVG canvas.

  • padding: number (optional, default: 0) - The padding around the tree.

  • stroke: string (optional, default: "grey") - The stroke color for the tree lines.

  • format: (n: number) => string (optional, default: (n) => n.toString()) - A function to format the display of time values.

  • chronoScale: boolean (optional, default: true) - If true, the width of the lines depends on the duration of the species.

  • presentTime: number (optional) - The current time to highlight in the tree.

  • children: (species: Species | undefined, showMenu: boolean, toggleShowMenu: (species: Species) => void) => React.ReactNode (optional) - Render prop to customize the menu content.

Rendering

The component renders an SVG element that contains the phylogenetic trees. It uses the PhTree component to recursively draw the tree structure for each species in the list. The children render prop is conditionally rendered based on the showMenu state, allowing for further customization of the menu content displayed when a species node is clicked.

Customization

The MultiplePhTrees component can be customized using the various props it accepts. Additionally, the children render prop allows for further customization of the menu content displayed when a species node is clicked.

Menu Component

The Menu component provides a user interface to edit and manage species data. It allows users to modify species attributes, add descendants or ancestors, and delete species.

Properties

  • species: SpeciesThe species for which the menu is displayed.
  • language: string (optional)The language code for localization.
  • open: boolean (optional)Controls the visibility of the menu.
  • onClose: () => void (optional)A callback function to close the menu.
  • saveSpecies: (s: Species, name: string, apparition: number, duration: number, description?: string) => void (optional)A callback function to save species data.
  • createDescendant: (s: Species, name: string, afterApparition: number, duration: number, description: string) => void (optional)A callback function to create a new descendant species.
  • createAncestor: (s: Species, name: string, previousApparition: number, duration: number, description: string) => void (optional)A callback function to create a new ancestor species.
  • deleteAncestor: () => void (optional)A callback function to delete an ancestor species.
  • deleteSpecies: () => void (optional) A callback function to delete a species.

State

  • name: stringThe name of the species.
  • apparition: numberThe appearance time of the species.
  • duration: numberThe duration of the species.
  • description: string | undefinedThe description of the species.
  • addDescendant: booleanControls the visibility of the descendant addition form.
  • addAncestor: boolean Controls the visibility of the ancestor addition form.

Methods

  • toggleAddDescendant: () => voidToggles the visibility of the descendant addition form.
  • toggleAddAncestor: () => voidToggles the visibility of the ancestor addition form.
  • uniqueDescendant: (s: Species) => boolean Checks if the species is the only descendant of its ancestor.

Rendering

The component renders a modal form with fields to edit species attributes. It conditionally renders forms to add descendants or ancestors based on the state. The form includes buttons to save changes, delete species, and close the menu.

Translation Functions

The application supports localization through a CSV file (translate.csv) that contains translation strings for different languages. The translate.tsx file provides functions to fetch and use these translations dynamically.

CSV File Structure (translate.csv)

The translate.csv file is structured as follows:

  • Columns:

    • code: A unique identifier for each translation string.
    • spanish: The translation in Spanish.
    • english: The translation in English.
  • Rows:

    • Each row represents a translation string, identified by its code.
    • The first row with the code value "lan" contains the language names (e.g., "Español" for Spanish, "English" for English).

Example CSV Content

code;spanish;english
lan;Español;English
ttl;Árbol Cronofilogenético;Chronophylogenetic Tree
nvlbl00;Escala;Scale
nvlbl01;Presente;Present
nvlbl02;Color;Color
nvlbl03;Repositorio;Repository
nvlbl04;Importar JSON;Import JSON
nvbtn00;Crear especie vacía;Create empty species
nvbtn00_0;Eliminar todas las especies;Delete all species
nvbtn01;Ejemplo;Example
nvbtn02;Descargar JSON;Download JSON
nvlbl05;Idioma;Language
nvlbl06;Escala Cronológica;Chronological Scale
splbl00;Nombre;Name
splbl01;Aparición;Apparition
splbl02;Duración;Duration
splbl03;Descripción;Description
spbtn00;Guardar;Save
spbtn01;Eliminar;Delete
spbtn02;Crear descendiente;Create descendant
spbtn03;Crear ancestro;Create ancestor
spbtn04;Quitar Ancestro;Remove Ancestor
spbtn04_0;Quitar Ancestros;Remove Ancestors
spbtn05;Cancelar;Cancel
cdbtn00;Crear;Create
cnfrm00;¿Estás seguro de que deseas quitar al ancestro de {0}?;Are you sure you want to remove the {0}'s ancestor?
cnfrm00_0;¿Estás seguro de que deseas quitar a los ancestros de {0}?;Are you sure you want to remove the {0}'s ancestors?
cnfrm01;¿Estás seguro de que deseas eliminar la especie {0}?;Are you sure you want to remove the {0} species?
cnfrm01_0;¿Estás seguro de que deseas eliminar la especie {0} junto a sus descendientes?;Are you sure you want to remove the {0} species along with its descendants?

How It Works

  1. Translation Lookup:
  • The codeText and codeTextAlt functions in translate.tsx fetch the translation data from the CSV file.
  • They search for the row with the matching code and retrieve the translation for the specified language.
  • If the translation contains placeholders (e.g., {0}), they are replaced with the provided arguments.
  1. Language Options:
  • The getLanguageOptions function retrieves the available languages from the CSV file by looking for the row with the code value "lan".
  • It returns a map of language codes (e.g., "spanish", "english") to their corresponding language names (e.g., "Español", "English").
  1. Dynamic Translation:
  • The application uses the codeText function to dynamically translate UI elements based on the selected language.
  • For example, buttons, labels, and confirmation messages are translated using the code values defined in the CSV file.

codeText

export const codeText = (code: string, language: string, arg: string[] = [], filePath: string = "/translate.csv"): string

Retrieves a translated string based on a given code and language. It also supports string interpolation using placeholders ({0}, {1}, etc.).

Parameters

  • code: string The code that identifies the translation string in the CSV file.
  • language: string The language code (e.g., "spanish", "english") for which the translation is requested.
  • arg: string[] (optional, default: []) An array of arguments to replace placeholders in the translated string.
  • filePath: string (optional, default: "/translate.csv") The path to the CSV file containing the translation data.

Returns

  • string: The translated string with placeholders replaced by the provided arguments. If the translation is not found, the function returns the original code.

codeTextAlt

export const codeTextAlt = async (code: string, language: string, arg: string[] = [], filePath: string = "/translate.csv"): Promise<string>

An asynchronous version of codeText. It fetches the translation data from the CSV file and retrieves the translated string.

Parameters

  • code: string The code that identifies the translation string in the CSV file.
  • language: string The language code (e.g., "spanish", "english") for which the translation is requested.
  • arg: string[] (optional, default: []) An array of arguments to replace placeholders in the translated string.
  • filePath: string (optional, default: "/translate.csv") The path to the CSV file containing the translation data.

Returns

  • Promise<string>: A promise that resolves to the translated string with placeholders replaced by the provided arguments. If the translation is not found, the function returns the original code.

getLanguageOptions

export const getLanguageOptions = (filePath: string = "/translate.csv"): Map<string, string>

Retrieves a map of available language options from the CSV file. The language options are stored in a row with the code "lan".

Parameters

  • filePath: string (optional, default: "/translate.csv") The path to the CSV file containing the translation data.

Returns

  • Map<string, string>: A map where the keys are language codes (e.g., "spanish", "english") and the values are the corresponding language names (e.g., "Español", "English").

Example Usage

Fetching a Translated String

codeText

const greeting = codeText("greeting", "spanish", ["Juan"]); //Example row: greeting; Hola, {0}; Hello, {0}
console.log(greeting); // Output: "Hola, Juan"

codeTextAlt

const greeting = await codeTextAlt("greeting", "spanish", ["Juan"]); //Example row: greeting; Hola, {0}; Hello, {0}
console.log(greeting); // Output: "Hola, Juan"

Fetching Language Options

const languageOptions = getLanguageOptions();
console.log(languageOptions.get("spanish")); // Output: "Español"

Adding New Languages

To add support for a new language (e.g., French):

  1. Add a new column to the CSV file (e.g., french).
  2. Populate the new column with translations for each code.
  3. Update the getLanguageOptions function to include the new language in the language options map.

Example CSV Update for French

code;spanish;english;french
lan;Español;English;Français
nvlbl00;Escala;Scale;Échelle
nvlbl01;Presente;Present;Présent
...

Supported Translation Codes

Below is a list of some of the translation codes used in the application:

CodeSpanishEnglish
ttlÁrbol CronofilogenéticoChronophylogenetic Tree
nvlbl00EscalaScale
nvlbl01PresentePresent
nvlbl02ColorColor
nvlbl03RepositorioRepository
nvlbl04Importar JSONImport JSON
nvbtn00Crear especie vacíaCreate empty species
nvbtn00_0Eliminar todas las especiesDelete all species
nvbtn01EjemploExample
nvbtn02Descargar JSONDownload JSON
nvlbl05IdiomaLanguage
nvlbl06Escala CronológicaChronological Scale
splbl00NombreName
splbl01ApariciónApparition
splbl02DuraciónDuration
splbl03DescripciónDescription
spbtn00GuardarSave
spbtn01EliminarDelete
spbtn02Crear descendienteCreate descendant
spbtn03Crear ancestroCreate ancestor
spbtn04Quitar AncestroRemove Ancestor
spbtn04_0Quitar AncestrosRemove Ancestors
spbtn05CancelarCancel
cdbtn00CrearCreate
cnfrm00¿Estás seguro de que deseas quitar al ancestro de {0}?Are you sure you want to remove the {0}'s ancestor?
cnfrm00_0¿Estás seguro de que deseas quitar a los ancestros de {0}?Are you sure you want to remove the {0}'s ancestors?
cnfrm01¿Estás seguro de que deseas eliminar la especie {0}?Are you sure you want to remove the {0} species?
cnfrm01_0¿Estás seguro de que deseas eliminar la especie {0} junto a sus descendientes?Are you sure you want to remove the {0} species along with its descendants?
1.0.9

4 months ago

1.0.8

5 months ago

1.0.7

5 months ago

1.0.6

5 months ago

1.0.5

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.10

4 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago