🍴 Meu Garfo é uma visualização em grafo dos CNPJs cuducos.tngl.io/meu-garfo
1

Configure Feed

Select the types of activity you want to include in your feed.

Dynamically calibrates layout density

+83 -16
+50 -14
src/Graph.elm
··· 6 6 import Types exposing (..) 7 7 8 8 9 - makeSim : Float -> Float -> List String -> List ( String, String ) -> Force.State String 10 - makeSim w h nodeIds links = 9 + makeSim : Float -> Float -> Float -> Float -> Float -> List String -> List ( String, String ) -> Force.State String 10 + makeSim w h manyBody collisionRadius linkDistance nodeIds links = 11 11 Force.iterations 200 12 12 (Force.simulation 13 - [ Force.manyBodyStrength -30 nodeIds 13 + [ Force.manyBodyStrength manyBody nodeIds 14 14 , Force.center (w / 2) (h / 2) 15 - , Force.customLinks 1 (List.map (\( s, t ) -> { source = s, target = t, distance = 50, strength = Nothing }) links) 16 - , Force.collision 20 nodeIds 15 + , Force.customLinks 1 (List.map (\( s, t ) -> { source = s, target = t, distance = linkDistance, strength = Nothing }) links) 16 + , Force.collision collisionRadius nodeIds 17 17 ] 18 18 ) 19 19 20 20 21 21 initSimulation : Float -> Float -> List String -> Force.State String 22 22 initSimulation w h nodeIds = 23 - makeSim w h nodeIds [] 23 + makeSim w h -30 20 50 nodeIds [] 24 24 25 25 26 26 layout : Model -> Model 27 27 layout model = 28 - { model 29 - | simulation = 30 - makeSim 31 - model.width 32 - model.height 33 - (Dict.keys model.nodes) 34 - (Set.toList model.edges) 35 - } 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 + } 36 72 37 73 38 74 isSimulating : Model -> Bool
+29 -2
src/Main.elm
··· 63 63 , pan = { x = 0, y = 0 } 64 64 , navKey = key 65 65 , url = url 66 + , manyBody = -150 67 + , collisionRadius = 50 68 + , linkDistance = 80 69 + , isInitialSearch = True 66 70 } 67 71 68 72 ( finalModel, initialCmd ) = ··· 172 176 , simulation = Graph.initSimulation model.width model.height [] 173 177 , pan = { x = 0, y = 0 } 174 178 , zoom = 1.0 179 + , manyBody = -150 180 + , collisionRadius = 50 181 + , linkDistance = 80 182 + , isInitialSearch = True 175 183 } 176 184 , Nav.pushUrl model.navKey ("#/grafo/" ++ unmasked) 177 185 ) ··· 205 213 , simulation = Graph.initSimulation model.width model.height [] 206 214 , pan = { x = 0, y = 0 } 207 215 , zoom = 1.0 216 + , manyBody = -150 217 + , collisionRadius = 50 218 + , linkDistance = 80 219 + , isInitialSearch = True 208 220 } 209 221 , Nav.pushUrl model.navKey ("#/conexao/" ++ id1 ++ "/" ++ id2) 210 222 ) ··· 242 254 , pending = Set.remove key model.pending 243 255 , visited = Set.insert key model.visited 244 256 } 257 + 258 + finalBaseModel = 259 + if model.isInitialSearch && Set.isEmpty baseModel.pending then 260 + { baseModel | isInitialSearch = False } 261 + 262 + else 263 + baseModel 245 264 in 246 265 case result of 247 266 Err apiErr -> ··· 250 269 List.filter isMatchingQuery model.currentQueries 251 270 |> List.head 252 271 in 253 - triggerNextQuery (handleApiError id url failedQuery apiErr baseModel) 272 + triggerNextQuery (handleApiError id url failedQuery apiErr finalBaseModel) 254 273 255 274 Ok response -> 256 275 let 257 276 ( updatedModel, newQueue, extraCmd ) = 258 - processResponse id response depth { baseModel | error = Nothing } 277 + processResponse id response depth { finalBaseModel | error = Nothing } 259 278 260 279 ( nextModel, nextCmd ) = 261 280 triggerNextQuery ··· 391 410 , simulation = Graph.initSimulation model.width model.height [] 392 411 , url = url 393 412 , activeTab = CnpjTab 413 + , manyBody = -150 414 + , collisionRadius = 50 415 + , linkDistance = 80 416 + , isInitialSearch = True 394 417 } 395 418 in 396 419 triggerNextQuery (enqueueQueries (queriesFor cnpj True 0) reset) ··· 418 441 , simulation = Graph.initSimulation model.width model.height [] 419 442 , url = url 420 443 , activeTab = ConnectionTab 444 + , manyBody = -150 445 + , collisionRadius = 50 446 + , linkDistance = 80 447 + , isInitialSearch = True 421 448 } 422 449 in 423 450 triggerNextQuery (enqueueQueries [ QueryRequest (id1 ++ ";" ++ id2) 0 (ConnectionQuery id1 id2) ] reset)
+4
src/Types.elm
··· 77 77 , pan : { x : Float, y : Float } 78 78 , navKey : Nav.Key 79 79 , url : Url 80 + , manyBody : Float 81 + , collisionRadius : Float 82 + , linkDistance : Float 83 + , isInitialSearch : Bool 80 84 } 81 85 82 86