Family Chart

repository·master·Indexed 20 days ago

https://github.com/donatso/family-chart

A D3.js-powered library for building interactive, highly customizable family tree visualizations. Version 0.9.0 is framework-agnostic, supporting React, Vue, Angular, Svelte, and vanilla JavaScript. It features interactive navigation (zoom/pan), TypeScript support, and a Visual Builder for code generation. The library is organized into three core components: the Chart API for overall management, the Card API for HTML/SVG node customization, and the EditTree API for real-time data manipulation and form management.

Tokens
12.1K
Snippets
35
Records
55
Agent score
72%

What's inside family-chart

  1. Overview of Family Chart

    master

    Family Chart is a D3.js-based visualization library designed for creating interactive, beautiful family trees. It is framework-agnostic and supports major JavaScript environments including React, Vue, Angular, Svelte, and vanilla JavaScript.

    Key capabilities include:

    • Interactive Navigation: Zoom, pan, and navigate complex family structures.
    • Customizable Styling: Full control over colors, fonts, and layout.
    • TypeScript Support: Includes full type definitions.
    • Multiple Card Types: Supports both SVG and HTML card components.
    • Real-time Updates: Ability to perform dynamic tree updates and modifications.
  2. How the three main components of Family Chart work together

    master

    The Family Chart library is organized into three core classes that manage different aspects of the visualization lifecycle:

    1. f3Chart (Chart Class): The primary entry point. It manages the overall visualization, including data orchestration, styling, tree layout, orientation, and the main update loop.
    2. f3Card (CardHtml Class): A sub-component of the chart used for node rendering. It specializes in HTML-based card customization, allowing you to define how individual family members are visually represented (images, custom HTML, dimensions, and interactive behaviors).
    3. f3EditTree (EditTree Class): An extension of the chart that enables data manipulation. It provides the UI and logic for adding, editing, or removing family members and relationships, including form management and undo/redo functionality.

    To use them, you typically initialize the f3Chart first, then chain or call methods to configure f3Card and f3EditTree based on your requirements.

  3. Integrate Family Chart with React

    master

    In React, use useRef to reference the container element and useEffect to initialize the chart after the component mounts. Ensure the chartRef div is returned in the JSX.

    import React, { useEffect, useRef } from 'react';
    import * as f3 from 'family-chart';
    import 'family-chart/styles/family-chart.css';
    
    const FamilyTree = () => {
      const chartRef = useRef(null);
    
      useEffect(() => {
        if (chartRef.current) {
          const data = [
            {
              "id": "1",
              "data": {"first name": "John", "last name": "Doe", "birthday": "1980", "gender": "M"},
              "rels": {"spouses": ["2"], "children": ["3"]}
            }
          ];
    
          const f3Chart = f3.createChart('#FamilyChart', data);
    
          f3Chart.setCardHtml()
            .setCardDisplay([["first name","last name"],["birthday"]]);
    
          f3Chart.updateTree({initial: true});
        }
      }, []);
    
      return <div className="f3" id="FamilyChart" ref={chartRef} style={{width: '100%', height: '900px', margin: 'auto', backgroundColor: 'rgb(33,33,33)', color: '#fff'}} />;
    };
    
    export default FamilyTree;
  4. Quick Start: Create a family tree with Family Chart

    master

    To create a basic interactive family tree, import the family-chart package and its CSS, define your data structure, and initialize the chart using createChart. You can then configure the card display (how information is shown on nodes) and the editing interface (how users modify data).

    Data Format

    Your data should be an array of objects containing:

    • id: A unique identifier.
    • data: An object containing person-specific attributes (e.g., first name, last name).
    • rels: An object defining relationships such as spouses, children, or parents using the IDs of related members.

    Implementation Steps

    1. Import family-chart and the required CSS.
    2. Call f3.createChart(selector, data) to initialize the visualization.
    3. Use .setCardHtml() to configure node card layouts.
    4. Use .editTree() to configure the editing interface.
    5. Call .updateTree({initial: true}) to render the chart.
    import * as f3 from 'family-chart';
    import 'family-chart/dist/styles/family-chart.css';
    
    // Your family tree data
    const data = [
      {
        "id": "1",
        "data": {"first name": "John", "last name": "Doe", "birthday": "1980", "gender": "M"},
        "rels": {"spouses": ["2"], "children": ["3"]}
      },
      {
        "id": "2",
        "data": {"first name": "Jane", "last name": "Doe", "birthday": "1982", "gender": "F"},
        "rels": {"spouses": ["1"], "children": ["3"]}
      },
      {
        "id": "3",
        "data": {"first name": "Bob", "last name": "Doe", "birthday": "2005", "gender": "M"},
        "rels": {"parents": ["1", "2"]}
      }
    ];
    
    // Create the chart
    const f3Chart = f3.createChart('#FamilyChart', data)
    
    const f3Card = f3Chart.setCardHtml()
      .setCardDisplay([["first name","last name"],["birthday"]]);
    
    const f3EditTree = f3Chart.editTree()
      .setFields(["first name","last name","birthday"]);
    
    f3Chart.updateTree({initial: true});
  5. Integrate Family Chart with Angular

    master

    In Angular, import the library and CSS. Initialize the chart within the ngOnInit lifecycle hook. You can cast the data as f3.Data for type safety.

    import { Component, ElementRef, OnInit } from '@angular/core';
    import * as f3 from 'family-chart';
    import 'family-chart/styles/family-chart.css';
    
    @Component({
      selector: 'app-family-chart',
      standalone: true,
      template: '<div class="f3" id="FamilyChart" style="width:100%;height:900px;margin:auto;background-color:rgb(33,33,33);color:#fff;"></div
    ',
    })
    export class FamilyTreeComponent implements OnInit {
      constructor(private elementRef: ElementRef) {}
    
      ngOnInit() {
        const data = [
          {
            "id": "1",
            "data": {"first name": "John", "last name": "Doe", "birthday": "1980", "gender": "M"},
            "rels": {"spouses": ["2"], "children": ["3"]}
          }
        ];
    
        const f3Chart = f3.createChart('#FamilyChart', data as f3.Data);
    
        f3Chart
          .setCardHtml()
          .setCardDisplay([['first name', 'last name'], ['birthday']]);
    
        f3Chart.updateTree({ initial: true });
      }
    }
  6. Use Family Chart via CDN

    master

    For simple HTML pages or quick testing, include the D3 library, the Family Chart script, and the Family Chart CSS via unpkg.

    <script src="https://unpkg.com/d3@7"></script>
    <link rel="stylesheet" href="https://unpkg.com/family-chart@latest/dist/styles/family-chart.css">
    <script type="module" src="https://unpkg.com/family-chart@latest"></script>
  7. Quick Start with NPM/ES6 Modules

    master

    To use Family Chart in a modern JavaScript environment, import the library and its CSS. Use f3.createChart(selector, data) to initialize the chart, then configure the card display and update the tree.

    import * as f3 from 'family-chart';
    import 'family-chart/dist/styles/family-chart.css';
    
    const data = [
      {
        "id": "1",
        "data": {"first name": "John", "last name": "Doe", "birthday": "1980", "gender": "M"},
        "rels": {"spouses": ["2"], "children": ["3"]}
      },
      {
        "id": "2",
        "data": {"first name": "Jane", "last name": "Doe", "birthday": "1982", "gender": "F"},
        "rels": {"spouses": ["1"], "children": ["3"]}
      },
      {
        "id": "3",
        "data": {"first name": "Bob", "last name": "Doe", "birthday": "2005", "gender": "M"},
        "rels": {"parents": ["1", "2"]}
      }
    ];
    
    const chart = f3.createChart('#FamilyChart', data);
    
    chart.setCardHtml()
      .setCardDisplay([["first name","last name"],["birthday"]]);
    
    chart.updateTree({initial: true});
  8. Access Installation and Data Format guides

    master

    For detailed implementation, refer to the following documentation guides:

    • Installation & Quick Start: Detailed steps to get the library running in your project.
    • Data Format: Documentation on the required data structure for rendering trees.
    • Getting Started Guide: A comprehensive setup and configuration guide.
  9. Integrate Family Chart with Vue

    master

    In Vue, import the library and CSS, then initialize the chart within the mounted lifecycle hook to ensure the DOM element exists.

    <template>
      <div class="f3" id="FamilyChart" style="width:100%;height:900px;margin:auto;background-color:rgb(33,33,33);color:#fff;"></div
    </template>
    
    <script>
    import * as f3 from 'family-chart';
    import 'family-chart/styles/family-chart.css';
    
    export default {
      name: 'FamilyTree',
      mounted() {
        const data = [
          {
            "id": "1",
            "data": {"first name": "John", "last name": "Doe", "birthday": "1980", "gender": "M"},
            "rels": {"spouses": ["2"], "children": ["3"]}
          }
        ];
        const f3Chart = f3.createChart('#FamilyChart', data);
    
        f3Chart.setCardHtml()
          .setCardDisplay([["first name","last name"],["birthday"]]);
    
        f3Chart.updateTree({initial: true});
      }
    };
    </script>
  10. Integrate Family Chart with Svelte

    master

    In Svelte, use the onMount lifecycle hook to initialize the chart. Use bind:this to get a reference to the container element.

    <script>
      import { onMount } from 'svelte';
      import * as f3 from 'family-chart';
      import 'family-chart/styles/family-chart.css';
    
      let chartContainer;
    
      onMount(() => {
        if (!chartContainer) return
    
        const data = [
          {
            "id": "1",
            "data": {"first name": "John", "last name": "Doe", "birthday": "1980", "gender": "M"},
            "rels": {"spouses": ["2"], "children": ["3"]}
          }
        ];
    
        const f3Chart = f3.createChart('#FamilyChart', data);
    
        f3Chart.setCardHtml()
          .setCardDisplay([["first name","last name"],["birthday"]]);
    
        f3Chart.updateTree({initial: true});
      });
    </script>
    
    <div class="f3" id="FamilyChart" bind:this={chartContainer} style="width:100%;height:900px;margin:auto;background-color:rgb(33,33,33);color:#fff;"></div