keechma-graph-data

0.1.0-SNAPSHOT


Example application that renders the graph data

dependencies

org.clojure/clojure
1.7.0
org.clojure/clojurescript
1.7.170
org.clojure/core.async
0.2.374
keechma
0.1.0-SNAPSHOT
(this space intentionally left almost blank)
 
(ns keechma-graph-data.core
  (:require [keechma.controller :as controller]
            [keechma.edb :as edb]
            [keechma.ui-component :as ui]
            [keechma.app-state :as app-state])
  (:require-macros [reagent.ratom :refer [reaction]]))
(enable-console-print!)

Define the initial graph data

(def user-data
  [{:id 1 :username "User #1" :favorite-users [2 3]}
   {:id 2 :username "User #2" :favorite-users [1]}
   {:id 3 :username "User #3" :favorite-users [2 1 3]}])

Process the data so the EntityDB knows how to handle relations

This function transforms [1,2,3] to [{:id 1}, {:id 2}, {:id 3}]. When the data is inserted into the EntityDB, it will set up the links to the real user entities.

(defn process-user-data
  [user-data]
  (map (fn [user]
         (assoc user :favorite-users
                (map (fn [favorite-user]
                       {:id favorite-user}) (:favorite-users user)))) user-data))

Set up the schema so users have relations to their favorite users

(def schema
  {:users {:id :id
           :relations {:favorite-users [:many :users]}}})
(defrecord DataController []
  controller/IController
  (params [_ _] true)
  (start [_ _ app-db]
    ;; Inserts the data into the application state
    (edb/insert-collection schema app-db :users :list (process-user-data user-data))))

Get the user list from the app state

(defn user-list
  [app-db]
  (reaction
   (edb/get-collection schema @app-db :users :list)))

Renders one user and a list of it's favorite users.

(:favorite-users user) returns a function which will return the list of favorite users for a user. This allows EntityDB to handle circular relations.

(defn user-renderer
  [user]
  [:tr {:key (:id user)}
   [:td (:username user)]
   [:td (clojure.string/join ", " (map #(:username %) ((:favorite-users user))))]])

Render the list of users. Each user is rendered by the user-renderer function.

(defn user-list-renderer
  [ctx]
  (fn []
    (let [user-list-sub (ui/subscription ctx :user-list)]
      [:table.table
       [:thead
        [:tr
         [:th "User"]
         [:th "Favorite Users"]]]
       [:tbody
        (map user-renderer @user-list-sub)]])))

Defines the renderer and subscription dependencies for the user list component.

(def user-list-component
  (ui/constructor {:renderer user-list-renderer
                   :subscription-deps [:user-list]}))
(def app-definition {:controllers {:data (->DataController)}
                     :subscriptions {:user-list user-list}
                     :components {:main user-list-component}
          :html-element (.getElementById js/document "app")})
(defonce running-app (clojure.core/atom))

Helper function that starts the application.

(defn start-app!
  []
  (reset! running-app (app-state/start! app-definition)))

Helper function that restarts the application whenever the code is hot reloaded.

(defn restart-app!
  []
  (let [current @running-app]
    (if current
      (app-state/stop! current start-app!)
      (start-app!))))
(restart-app!)
(defn on-js-reload []
  ;; optionally touch your app-state to force rerendering depending on
  ;; your application
  ;; (swap! app-state update-in [:__figwheel_counter] inc))