Effortlessly understand large (and small) Kotlin/Java classes π
You can try this sample interactive graph for Signal Android App's StoryViewerPageFragment class.
Visualizing ConversationParentFragment.java, a 3,510 LOC class from Signal Android App.
$ brew tap redgreenio/tap
$ brew install twd
$ brew upgrade twd
Build the project first and then run the command line tool.
$ twd watch io.redgreen.ExampleClass
The command will start a web server on port 7070. Go to localhost:7070
in your browser to see the diagram.
The diagram will be updated in real-time as you make changes to the source code and compile the project.
For more options, run twd watch --help
.
Tumbleweed is under development. The current reference for production use is making the tool as accurate as jQAssistant. Sometimes, we have to process a lot of data to understand the gap between these two.
The following commands are useful for development and once the project attains version one status, we'll hide these commands from users but may still continue to use them for developing Tumbleweed.
$ twd json ExampleClass
This command will print the JSON representation of the class to the console. This is the data that is used to render the bilevel edge bundling graph on ObservableHQ.
$ twd view my-class.json
This command will start a web server and visualize the specified JSON file in the browser. It is best used when comparing a class visualization using Tumbleweed and a JSON file derived for the same class using jQAssistant.
$ twd convert jqassistant-query-result.csv
Converts class member relationships query result from jQAssistant to JSON format that can be visualized by Tumbleweed.
$ twd diff -b jqassistant-graph.json -i tumbleweed-graph.json
Compares and prints the differences between a jQAssistant and a Tumbleweed graph.
"${signature.concise} ${if (owner.contains("$")) "[${owner.substring(owner.indexOf('$'))}]" else ""}"
"${signature.concise} ${if (owner.contains("$")) "[${owner.substring(owner.indexOf('$'))}]" else ""}"
"${source.signature.concise} ${if (source.owner.contains("$")) "[${source.owner.substring(source.owner.indexOf('$'))}]" else ""} -${type.name.first()}-> ${target.signature.concise} ${if (target.owner.contains("$")) "[${target.owner.substring(target.owner.indexOf('$'))}]" else ""}"
- Kotlin companion objects are not yet supported.
Copyright (c) 2022-Present, Ragunath Jawahar
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright 2018β2020 Observable, Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.