Skip to content

Commit

Permalink
Merge branch 'recycler'
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
#	graphview/build.gradle
#	graphview/src/main/AndroidManifest.xml
  • Loading branch information
GregorBlock committed Apr 10, 2021
2 parents 785decb + b66e1a5 commit 53db97a
Show file tree
Hide file tree
Showing 55 changed files with 1,178 additions and 1,502 deletions.
184 changes: 90 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,137 +3,133 @@ GraphView

Android GraphView is used to display data in graph structures.

![alt Logo](image/GraphView_logo.png "Graph Logo")
![alt Logo](image/GraphView_logo.jpg "Graph Logo")

Overview
========
The library is designed to support different graph layouts and currently works with small graphs only.
The library can be used within `RecyclerView` and currently works with small graphs only.

**This project is currently experimental and the API subject to breaking changes without notice.**


Download
========
The library is only available on MavenCentral. Please add this code to your build.gradle file on project level:
```gradle
allprojects {
repositories {
...
mavenCentral()
}
}
```

```groovy
And add the dependency to the build.gradle file within the app module:
```gradle
dependencies {
implementation 'de.blox:graphview:0.7.1'
implementation 'dev.bandb.graphview:graphview:0.8.1'
}
```
Layouts
======
### Tree
Uses Walker's algorithm with Buchheim's runtime improvements (`BuchheimWalkerAlgorithm` class). Supports different orientations. All you have to do is using the `BuchheimWalkerConfiguration.Builder.setOrientation(int)` with either `ORIENTATION_LEFT_RIGHT`, `ORIENTATION_RIGHT_LEFT`, `ORIENTATION_TOP_BOTTOM` and
Uses Walker's algorithm with Buchheim's runtime improvements (`BuchheimWalkerLayoutManager` class). Currently only the `TreeEdgeDecoration` can be used to draw the edges. Supports different orientations. All you have to do is using the `BuchheimWalkerConfiguration.Builder.setOrientation(int)` with either `ORIENTATION_LEFT_RIGHT`, `ORIENTATION_RIGHT_LEFT`, `ORIENTATION_TOP_BOTTOM` and
`ORIENTATION_BOTTOM_TOP` (default). Furthermore parameters like sibling-, level-, subtree separation can be set.
### Directed graph
Directed graph drawing by simulating attraction/repulsion forces. For this the algorithm by Fruchterman and Reingold (`FruchtermanReingoldAlgorithm` class) was implemented.
Directed graph drawing by simulating attraction/repulsion forces. For this the algorithm by Fruchterman and Reingold (`FruchtermanReingoldLayoutManager` class) was implemented. To draw the edges you can use `ArrowEdgeDecoration` or `StraightEdgeDecoration`.
### Layered graph
Algorithm from Sugiyama et al. for drawing multilayer graphs, taking advantage of the hierarchical structure of the graph (`SugiyamaAlgorithm` class). You can also set the parameters for node and level separation using the `SugiyamaConfiguration.Builder`.
Algorithm from Sugiyama et al. for drawing multilayer graphs, taking advantage of the hierarchical structure of the graph (`SugiyamaLayoutManager` class). Currently only the `SugiyamaArrowEdgeDecoration` can be used to draw the edges. You can also set the parameters for node and level separation using the `SugiyamaConfiguration.Builder`.

Usage
======
Using GraphView is not much different than using RecyclerView.
Add GraphView to your layout file.
GraphView must be integrated with `RecyclerView`.
For this you’ll need to add a `RecyclerView` to your layout and create an item layout like usually when working with `RecyclerView`.

```xml
<com.otaliastudios.zoom.ZoomLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:hasClickableChildren="true">

<de.blox.graphview.GraphView
android:id="@+id/graph"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:lineColor="@android:color/holo_blue_dark"
app:lineThickness="2dp"
app:useMaxSize="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</com.otaliastudios.zoom.ZoomLayout>
```

Currently GraphView must be used together with a Zoom Engine like [ZoomLayout](https://github.com/natario1/ZoomLayout). To change the zoom values just use the different attributes described in the ZoomLayout project site.

Then define the node layout, e.g. ```node.xml```. You can make the node Layout as complex as you want.
```xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
```

To create a graph, we need to instantiate the `Graph` class. Next bind your graph to GraphView, for that you must extend from the `GraphView.Adapter` class.

```java
public class GraphActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GraphView graphView = findViewById(R.id.graph);

// example tree
final Graph graph = new Graph();
final Node node1 = new Node("Parent");
final Node node2 = new Node("Child 1");
final Node node3 = new Node("Child 2");

graph.addEdge(node1, node2);
graph.addEdge(node1, node3);

// you can set the graph via the constructor or use the adapter.setGraph(Graph) method
GraphAdapter adapter = new GraphAdapter<GraphView.ViewHolder>(graph) {

@NonNull
@Override
public GraphView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.node, parent, false);
return new SimpleViewHolder(view);
}

@Override
public void onBindViewHolder(GraphView.ViewHolder viewHolder, Object data, int position) {
((SimpleViewHolder) viewHolder).textView.setText(data.toString());
}
};
graphView.setAdapter(adapter);

// set the algorithm here
final BuchheimWalkerConfiguration configuration = new BuchheimWalkerConfiguration.Builder()
.setSiblingSeparation(100)
.setLevelSeparation(300)
.setSubtreeSeparation(300)
.setOrientation(BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM)
.build();
graphView.setLayout(new BuchheimWalkerAlgorithm(configuration));
To create a graph, we need to instantiate the `Graph` class. Next submit your graph to your Adapter, for that you must extend from the `AbstractGraphAdapter` class.

```kotlin
private void setupGraphView {
val recycler = findViewById(R.id.recycler)

// 1. Set a layout manager of the ones described above that the RecyclerView will use.
val configuration = BuchheimWalkerConfiguration.Builder()
.setSiblingSeparation(100)
.setLevelSeparation(100)
.setSubtreeSeparation(100)
.setOrientation(BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM)
.build()
recycler.layoutManager = BuchheimWalkerLayoutManager(context, configuration)

// 2. Attach item decorations to draw edges
recycler.addItemDecoration(TreeEdgeDecoration())

// 3. Build your graph
val graph = Graph()
val node1 = Node("Parent")
val node2 = Node("Child 1")
val node3 = Node("Child 2")

graph.addEdge(node1, node2)
graph.addEdge(node1, node3)

// 4. You will need a simple Adapter/ViewHolder.
// 4.1 Your Adapter class should extend from `AbstractGraphAdapter`
adapter = object : AbstractGraphAdapter<NodeViewHolder>() {

// 4.2 ViewHolder should extend from `RecyclerView.ViewHolder`
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NodeViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.node, parent, false)
return NodeViewHolder(view)
}

override fun onBindViewHolder(holder: NodeViewHolder, position: Int) {
holder.textView.text = getNodeData(position).toString()
}
}.apply {
// 4.3 Submit the graph
this.submitGraph(graph)
recycler.adapter = this
}
}
```

Your ViewHolder class should extend from `GraphView.ViewHolder`:
```java
class SimpleViewHolder extends GraphView.ViewHolder {
TextView textView;

SimpleViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text);
Customization
======
You can change the edge design by supplying your custom paint object to your edge decorator.
```kotlin
val edgeStyle = Paint(Paint.ANTI_ALIAS_FLAG).apply {
strokeWidth = 5f
color = Color.BLACK
style = Paint.Style.STROKE
strokeJoin = Paint.Join.ROUND
pathEffect = CornerPathEffect(10f)
}
}

recyclerView.addItemDecoration(TreeEdgeDecoration(edgeStyle))
```

Customization
=============

To use the custom attributes you have to add the namespace first: ```
xmlns:app="http://schemas.android.com/apk/res-auto"```

| Attribute | Format | Example | Explanation|
|------------------|-----------|--------------------------------|------------|
| lineThickness | Dimension | 10dp | Set how thick the connection lines should be
| lineColor | Color | "@android:color/holo_red_dark" | Set the color of the connection lines
| useMaxSize | Boolean | true | Use the same size for each node

Each of the attributes has a corresponding setter in the GraphView class, if you want to use it programmatically.
If you want that your nodes are all the same size you can set `useMaxSize` to `true`. The biggest node defines the size for all the other nodes.
```kotlin
recyclerView.layoutManager = BuchheimWalkerLayoutManager(this, configuration).apply {
useMaxSize = true
}
```

Examples
========
Expand All @@ -149,7 +145,7 @@ Examples
License
=======

Copyright 2020 Team-Blox
Copyright 2019 - 2021 Block & Block

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -161,4 +157,4 @@ License
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.
limitations under the License.
10 changes: 7 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.72'
ext.kotlin_version = '1.4.31'
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:4.1.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

classpath 'com.vanniktech:gradle-maven-publish-plugin:0.13.0'
classpath 'org.jetbrains.dokka:dokka-gradle-plugin:1.4.10.2'
}
}

allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
}
Expand Down
19 changes: 18 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,21 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true
android.useAndroidX=true
GROUP=dev.bandb.graphview
POM_ARTIFACT_ID=graphview
VERSION_NAME=0.8.1
POM_NAME=graphview
POM_PACKAGING=aar
POM_DESCRIPTION=Android GraphView is used to display data in graph structures.
POM_INCEPTION_YEAR=2021
POM_URL=https://github.com/oss-bandb/GraphView
POM_SCM_URL=https://github.com/oss-bandb/GraphView
POM_SCM_CONNECTION=scm:[email protected]:oss-bandb/GraphView.git
POM_SCM_DEV_CONNECTION=scm:[email protected]:oss-bandb/GraphView.git
POM_LICENCE_NAME=The Apache Software License, Version 2.0
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENCE_DIST=repo
POM_DEVELOPER_ID=bandb
POM_DEVELOPER_NAME=Block & Block
POM_DEVELOPER_URL=https://github.com/oss-bandb
52 changes: 0 additions & 52 deletions gradle/bintray.gradle

This file was deleted.

41 changes: 0 additions & 41 deletions gradle/install.gradle

This file was deleted.

Loading

0 comments on commit 53db97a

Please sign in to comment.