All Projects β†’ peterszerzo β†’ elm-arborist

peterszerzo / elm-arborist

Licence: MIT license
Parameterized 🌲tree🌲-editor for Elm

Programming Languages

elm
856 projects

Projects that are alternatives of or similar to elm-arborist

Merkle tree
A merkle tree is a data structure used for efficiently summarizing sets of data, often one-time signatures.
Stars: ✭ 68 (+19.3%)
Mutual labels:  tree-structure
Containers
This library provides various containers. Each container has utility functions to manipulate the data it holds. This is an abstraction as to not have to manually manage and reallocate memory.
Stars: ✭ 125 (+119.3%)
Mutual labels:  tree-structure
Graphview
Flutter GraphView is used to display data in graph structures. It can display Tree layout, Directed and Layered graph. Useful for Family Tree, Hierarchy View.
Stars: ✭ 152 (+166.67%)
Mutual labels:  tree-structure
Mindmap Layouts
automatic layout algorithms for mindmaps
Stars: ✭ 103 (+80.7%)
Mutual labels:  tree-structure
Calculist
the open source thinking tool for problem solvers
Stars: ✭ 122 (+114.04%)
Mutual labels:  tree-structure
Pbtreeview
An UITreeView implementation from UITableView that Apple missed in its UIKit framework. And it is in pure Swift.
Stars: ✭ 128 (+124.56%)
Mutual labels:  tree-structure
Buckets Js
A complete, fully tested and documented data structure library written in pure JavaScript.
Stars: ✭ 1,128 (+1878.95%)
Mutual labels:  tree-structure
Arrow Meta
Functional companion to Kotlin's Compiler
Stars: ✭ 246 (+331.58%)
Mutual labels:  tree-structure
Closure tree
Easily and efficiently make your ActiveRecord models support hierarchies
Stars: ✭ 1,665 (+2821.05%)
Mutual labels:  tree-structure
Array To Tree
Convert a plain array of nodes (with pointers to parent nodes) to a nested data structure
Stars: ✭ 141 (+147.37%)
Mutual labels:  tree-structure
Go Algorithms
Algorithms and data structures for golang
Stars: ✭ 1,529 (+2582.46%)
Mutual labels:  tree-structure
Bplustree
A minimal but extreme fast B+ tree indexing structure demo for billions of key-value storage
Stars: ✭ 1,598 (+2703.51%)
Mutual labels:  tree-structure
Kdtree
Absolute balanced kdtree for fast kNN search.
Stars: ✭ 131 (+129.82%)
Mutual labels:  tree-structure
Skov
A visual programming environment.
Stars: ✭ 84 (+47.37%)
Mutual labels:  tree-structure
Relation Classification Using Bidirectional Lstm Tree
TensorFlow Implementation of the paper "End-to-End Relation Extraction using LSTMs on Sequences and Tree Structures" and "Classifying Relations via Long Short Term Memory Networks along Shortest Dependency Paths" for classifying relations
Stars: ✭ 167 (+192.98%)
Mutual labels:  tree-structure
Ecola
Tree editor for touch screens
Stars: ✭ 64 (+12.28%)
Mutual labels:  tree-structure
Tempy
Python Object Oriented Html Templating System
Stars: ✭ 126 (+121.05%)
Mutual labels:  tree-structure
Finderjs
Browse hierarchical data in columns, similar to OS X's Finder
Stars: ✭ 247 (+333.33%)
Mutual labels:  tree-structure
Laravel Tournaments
Laravel Package that allows you to generate customizable tournaments trees.
Stars: ✭ 196 (+243.86%)
Mutual labels:  tree-structure
Data structure and algorithms library
A collection of classical algorithms and data-structures implementation in C++ for coding interview and competitive programming
Stars: ✭ 133 (+133.33%)
Mutual labels:  tree-structure
  🌲           🌲                             🌲          
 🌲🌲   🌲🌲 🌲      🌲   🌲  🌲   🌲     🌲  🌲      🌲🌲             🌲    
🌲🌲🌲  🌲🌲🌲 🌲  🌲🌲🌲 🌲🌲  🌲  🌲🌲🌲 🌲🌲🌲   🌲 🌲🌲        🌲🌲      🌲   

elm-arborist

Drag-and-drop interface to edit, dissect and-rearrange tree structures, with nodes holding any data type you wish. Here is a demo, and here some docs.

Getting started

TLDR: simple app example (run with cd examples && elm reactor, then open http://localhost:8000/Simple.elm)

First things first, we need to specify what kind of data structure our tree's nodes will hold. For this demo, it will be a record with a question and an answer.

type alias MyNode =
    { question : String
    , answer : String
    }

exampleNode = MyNode "How are you?" "Fine thanks"

We can then use the Arborist.Tree module to recursively construct a tree structure:

import Arborist.Tree as Tree

tree : Tree.Tree MyNode
tree =
  Tree.Node (MyNode "Q1" "A1")
    [ Tree.Node (MyNode "Q2" "A2") []
    , Tree.Node (MyNode "Q3" "A3")
        [ Tree.Node ( "Q4", "A4" )
        ]
    ]

Now, we can now define a model for your app:

import Arborist
import Arborist.Tree as Tree

type alias Model =
  { tree : Tree.Tree MyNode
  , arborist : Arborist.State
  }

Next, we configure the editor:

arboristSettings : List (Arborist.Setting MyNode)
arboristSettings =
    [ Settings.keyboardNavigation True
    , Settings.defaultNode (MyNode "A" "Q")
    , Settings.nodeWidth 100
    , Settings.level 80
    , Settings.gutter 20
    ]

Rendering the editor will look like this:

view : Model -> Html Msg
view model =
    Arborist.view
        []
        { state = model.arborist
        , tree = model.tree
        , settings = arboristSettings
        -- We get to these two in a second
        , nodeView = nodeView
        , toMsg = Arborist
        }

Now let's look at the two bits we left out: nodeView and toMsg.

nodeView

This function specifies how a node should be displayed within its bounding box, and looks like this:

-- Don't worry about `context` for now
nodeView : Arborist.NodeView MyNode Msg
nodeView context maybeNode =
    case maybeNode of
        Just node ->
            text node.question

        Nothing ->
            text "+ add node"

toMsg

Arborist uses the teach-me-how-to-message pattern, passing an Arborist.Updater to your app's update function. The updater is a function that works out the new tree and new state based on the previous tree and previous state.

type Msg
    -- This is the message constructor that goes into the `toMsg` field above
    = Arborist (Arborist.Updater MyNode)

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Arborist updater ->
            let
                ( newState, newTree ) =
                    updater model.arborist model.tree
            in
            ( { model
                | arborist = newState
                , tree = newTree
              }
            , Cmd.none
            )

Arborist cannot give new values straight away because mouse events are fired so quickly that they can undo each others' changes in the runtime, hence the complexity in the update logic above.

And that's it - your very own tree editor is ready.

Going further

Context

The context object exposed in the nodeView function above provides, as its name suggests, contextual information to the node when it is rendered, including their parent node and list of siblings. You may for instance want to signal to the user that a child can't be older than their parent in the family tree as they edit it, but traversing the tree to find that information is tedious and inefficient - so Arborist gives you access to it directly.

This should work for a large number of tree editing cases. If you need a broader context, you will need to traverse the tree yourself.

UX goodies

In the settings module, you will find setup instructions for advanced features like node clustering and keyboard navigation. For a real-world example, have a look at the elm-arborist landing page.

Contributing

Contributions welcome - please feel free to go ahead with issues and PR's, or reach out to me on Elm Slack at @peterszerzo.

License

MIT.

🌲🌲🌲  🌲🌲🌲 🌲  🌲🌲🌲 🌲🌲  🌲  🌲🌲🌲 🌲🌲🌲   🌲 🌲🌲        🌲🌲      🌲   
 🌲🌲   🌲🌲 🌲      🌲   🌲  🌲   🌲     🌲  🌲      🌲🌲             🌲    
  🌲           🌲                             🌲          
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].