🍴 Meu Garfo é uma visualização em grafo dos CNPJs
cuducos.tngl.io/meu-garfo
1module Graph exposing (initSimulation, isSimulating, layout, tick)
2
3import Dict
4import Force
5import Set
6import Types exposing (..)
7
8
9makeSim : Float -> Float -> Float -> Float -> Float -> List String -> List ( String, String ) -> Force.State String
10makeSim w h manyBody collisionRadius linkDistance nodeIds links =
11 Force.iterations 200
12 (Force.simulation
13 [ Force.manyBodyStrength manyBody nodeIds
14 , Force.center (w / 2) (h / 2)
15 , Force.customLinks 1 (List.map (\( s, t ) -> { source = s, target = t, distance = linkDistance, strength = Nothing }) links)
16 , Force.collision collisionRadius nodeIds
17 ]
18 )
19
20
21initSimulation : Float -> Float -> List String -> Force.State String
22initSimulation w h nodeIds =
23 makeSim w h -30 20 50 nodeIds []
24
25
26layout : Model -> Model
27layout model =
28 if model.isInitialSearch then
29 let
30 nodeCount =
31 Dict.size model.nodes
32
33 t =
34 clamp 0.0 1.0 ((toFloat nodeCount - 5) / 20)
35
36 manyBody =
37 -150 + t * 120
38
39 collisionRadius =
40 50 - t * 30
41
42 linkDistance =
43 80 - t * 30
44 in
45 { model
46 | manyBody = manyBody
47 , collisionRadius = collisionRadius
48 , linkDistance = linkDistance
49 , simulation =
50 makeSim
51 model.width
52 model.height
53 manyBody
54 collisionRadius
55 linkDistance
56 (Dict.keys model.nodes)
57 (Set.toList model.edges)
58 }
59
60 else
61 { model
62 | simulation =
63 makeSim
64 model.width
65 model.height
66 model.manyBody
67 model.collisionRadius
68 model.linkDistance
69 (Dict.keys model.nodes)
70 (Set.toList model.edges)
71 }
72
73
74isSimulating : Model -> Bool
75isSimulating model =
76 not (Dict.isEmpty model.nodes) && not (Force.isCompleted model.simulation)
77
78
79tick : Model -> Model
80tick model =
81 if not (isSimulating model) then
82 model
83
84 else
85 let
86 ( nextSim, nextNodes ) =
87 Force.tick model.simulation (Dict.values model.nodes)
88
89 updatedNodes =
90 List.foldl (\n acc -> Dict.insert n.id n acc) model.nodes nextNodes
91 in
92 { model | simulation = nextSim, nodes = updatedNodes }