• Stars
    star
    528
  • Rank 81,325 (Top 2 %)
  • Language
    Kotlin
  • License
    MIT License
  • Created over 4 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Doughnut-like graph view capable of displaying multiple datasets with assignable colors

Donut

Download Build Status Android Arsenal Android Weekly License Jetpack Compose

Donut is an Android library which helps you to easily create beautiful doughnut-like charts.

Installation

module/build.gradle:

dependencies {
    implementation("app.futured.donut:donut:$version")

    // If you want to use Jetpack Compose version then use only this one dependency
    implementation("app.futured.donut:donut-compose:$version")
}

Features

DonutProgressView is a configurable doughnut-like chart view capable of displaying multiple sections with assignable colors. It supports animations and features a gap at the top, which makes it look like a gauge (or tasty bitten-off donut - that's why the name).

Header

The view automatically scales it's sections proportionally to their values once it gets filled up. This allows you to show your users their daily progresses, reached goals, etc.

Usage

Place the view in your layout

<app.futured.donut.DonutProgressView
    android:id="@+id/donut_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:donut_bgLineColor="@color/cloud"
    app:donut_gapWidth="20"
    app:donut_gapAngle="270"
    app:donut_strokeWidth="16dp"/>

Submit data to the view

val section1 = DonutSection(
    name = "section_1",
    color = Color.parseColor("#FB1D32"),
    amount = 1f
)

val section2 = DonutSection(
    name = "section_2",
    color = Color.parseColor("#FFB98E"),
    amount = 1f
)

donut_view.cap = 5f
donut_view.submitData(listOf(section1, section2))

You'll get something like this:

View with cap unexceeded

About the data cap

Once the sum of all section values exceeds view's cap property, the view starts to scale it's sections proportionally to their amounts along it's length. E.g. if we, in the upper example, set cap to donut_view.cap = 1f (section1.amount + section2.amount > 1f), we would get something like this:

View with cap exceeded

Submitting data

The view accepts list of DonutSection objects that define data to be displayed. Each DonutSection object holds section's unique name (string), it's color (color int) and section's value. (Note: the view uses unique name for each section to resolve it's internal state and animations, and throws IllegalStateException if multiple sections with same name are submitted.)

val waterAmount = DonutSection(
    name = "drink_amount_water",
    color = Color.parseColor("#03BFFA"),
    amount = 1.2f
)

You have to submit new list of sections everytime you want to modify displayed data, as DonutSection object is immutable.

donut_view.submitData(listOf(waterAmount))

Granular controls

The view also provides methods for more granular control over displayed data. You can use addAmount, setAmount and removeAmount methods to add, set or remove specified amounts from displayed sections.

Adding amount
donut_view.addAmount(
    sectionName = "drink_amount_water",
    amount = 0.5f,
    color = Color.parseColor("#03BFFA") // Optional, pass color if you want to create new section
)

The addAmount adds specified amount to section with provided name. What if section does not yet exist? This method has one optional color parameter (default value is null) - when called, and there isn't already displayed any section with provided name and color parameter was specified, the new DonutSection with provided name, amount and color will be automatically created internally for you. If you leave the color param null while trying to add value to non-existent section, nothing happens.

Setting amount
donut_view.setAmount(
    sectionName = "drink_amount_water",
    amount = 2.5f
)

The setAmount methods sets specified amount to section with provided name. If provided amount is equal or less than 0, section and corresponding progress line are automatically removed after animation. If view does not contain specified section, nothing happens.

Removing amount
donut_view.removeAmount(
    sectionName = "drink_amount_water",
    amount = 0.1f
)

The removeAmount simply subtracts specified amount from any displayed section. If resulting amount is equal or less than 0, section and corresponding progress line are automatically removed after animation. If view does not contain specified section, nothing happens.

Get and clear data

If you want to get currently displayed data, call getData() method which returns immutable list of all displayed DonutSection objects. To clear displayed data, call clear() method.

Each call to a data method (submit, add, set, remove, clear) results in view automatically resolving and animating to the new state.

Customization

The view allows you to configure various properties to let you create a unique style that fits your needs. They can be changed either via XML attributes, or at runtime via property access.

XML attributes

Name Default value Description
donut_cap 1.0f View's cap property
donut_strokeWidth 12dp Width of background and section lines in dp
donut_strokeCap round The paint cap used for all lines. Can be either 'round' or 'butt'
donut_bgLineColor #e7e8e9 Color of background line
donut_gapWidth 45° Width of the line gap in degrees
donut_gapAngle 90° Position of the line gap around the view in degrees
donut_direction clockwise Progress lines direction (clockwise or anticlockwise)
donut_animateChanges true Animation enabled flag, if true, the view will animate it's state changes (enabled by default)
donut_animationInterpolator DecelerateInterpolator Interpolator to be used in state change animations
donut_animationDuration 1000 ms Duration of state change animations in ms

In addition to these XML attributes, the view features masterProgress property (0f to 1f) that can be changed programatically. It controls percentual progress of all lines, including the background line, which allows you to get creative with startup animations, etc.

Jetpack Compose version

This library is implemented as a standalone module also for Jetpack Compose. It has (almost) the same features as the original implementation, but it supports a wider variety of animations.

@Composable
fun Sample() {
    DonutProgress(
        model = DonutModel(
            cap = 8f,
            masterProgress = 1f,
            gapWidthDegrees = 270f,
            gapAngleDegrees = 90f,
            strokeWidth = 40f,
            backgroundLineColor = Color.LightGray,
            sections = listOf(
                DonutSection(amount = 1f, color = Color.Cyan),
                DonutSection(amount = 1f, color = Color.Red),
                DonutSection(amount = 1f, color = Color.Green),
                DonutSection(amount = 0f, color = Color.Blue)
            )
        ),
        config = DonutConfig(
            gapAngleAnimationSpec = spring()
            // ...
        )
    )
}

Sample app

The quickest way to explore different styles is to try the sample app, which contains an interactive playground with buttons and sliders to fiddle with.

Playground

Contributors

Current maintainer and main contributor for the original version is Matej Semančík and for Jetpack Compose version is Martin Sumera

Licence

Donut is available under MIT license. See LICENSE file for more information.

More Repositories

1

hauler

Library with swipe to dismiss Activity gesture implementation
Kotlin
435
star
2

TFBubbleItUp

Custom view for writing tags, contacts and etc. - written in Swift
Swift
330
star
3

Sonar

Radar style view written in swift
Swift
129
star
4

arkitekt

Arkitekt is a set of architectural tools based on Android Architecture Components, which gives you a solid base to implement the concise, testable and solid application.
Kotlin
120
star
5

TFTransparentNavigationBar

Custom transition between controllers in UINavigationController that makes navigation bar transparent on specified controllers
Swift
46
star
6

sheet-happens

Gradle plugin for generating Android / KMP string resources from Google Spreadsheets.
Kotlin
44
star
7

arkitekt-kmm

KMM library for UseCase abstraction
Kotlin
44
star
8

iOS-templates

Templates for MVVM-C architecture
Makefile
32
star
9

FuntastyKit

A collection of Swift utilities and protocols used in our projects
Swift
30
star
10

MVVM-C-Example

Example project for MVVM-C architecture in Swift
Swift
29
star
11

infinity

[Deprecated] Infinite paginated RecyclerView scrolling
Java
27
star
12

FTAPIKit

Declarative and generic REST API framework using Codable.
Swift
19
star
13

Engineering-Handbook

Best practices and guidelines for developing apps in Futured
15
star
14

Gutenberg

Tiny library for generating attributed string with emoticons as images
Shell
14
star
15

bitrise-step-apk-info

Ruby
11
star
16

CellKit

Table View and Collection View data source wrapper
Swift
10
star
17

FormStateKit

A Swift package for simple management of forms and their fields. Focused on SwiftUI.
Swift
9
star
18

FTPropertyWrappers

Property wrappers for User Defaults, Keychain, StoredSubject and synchronization.
Swift
8
star
19

TFTableDescriptor

iOS Library / Simple table descriptor with dynamic cell height support
Objective-C
6
star
20

taste

[Deprecated]
Java
6
star
21

danger

The Danger rules we use at @futuredapp
Ruby
6
star
22

LocationManager

Swift
6
star
23

kmp-futured-template

Template for creating Kotlin Multiplatform applications at Futured.
Kotlin
6
star
24

tasting

Android UI Automator wrapper for human-like scenario testing
Kotlin
6
star
25

Monkey-Madness

Easy to use ADB monkey command line wrapper
Shell
6
star
26

bitrise-step-ipa-info

Ruby
4
star
27

Funtasty-iOS-Playbook

Conventions for writing iOS applications
4
star
28

Realm-Codegen

Code Generation of Realm model files in Swift using Sourcery
Swift
2
star
29

OpenAPI-Project-Template

Template for OpenAPI specifications
Makefile
2
star
30

android-project-template

Kotlin
2
star
31

ui-test-examples

xcode ui test examples
Swift
2
star
32

f-academy-project-android

Kotlin
2
star
33

android-project-template-compose

Kotlin
1
star
34

brmo2023-kmm-talk

Code for the "KMM: Shared Navigation -- Finding The Sweet Spot" talk presented at BrMo2023 & Betsys Mobile dev meetup 2023
Kotlin
1
star
35

FCodeWars

1
star
36

FTLogKit

Yet another logging framework for Apple platforms
Swift
1
star
37

.github

1
star
38

SwiftMonkeys

Monkeys for UI automated testing. Also known as UI/Application Exerciser Monkey.
Objective-C
1
star
39

TFSlideControl

Swift
1
star
40

FTTestingKit

Mockups and async extension to XCTestCase
Swift
1
star
41

dev-academy-ios

Swift
1
star
42

FuturedKit

SwiftUI state management tools, resources and views used by Futured.
Swift
1
star
43

iOS-project-template

Template for creating iOS projects we use @futuredapp.
Ruby
1
star