├── .editorconfig
├── .github
├── CODEOWNERS
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── Bug_report.md
│ └── Feature_request.md
├── pull_request_template.md
└── workflows
│ ├── android.yml
│ └── publish.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
├── .gitignore
├── api
│ └── app.api
├── build.gradle.kts
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── kotlin
│ └── io
│ │ └── androidpoet
│ │ └── drafterdemo
│ │ ├── ChartContainer.kt
│ │ ├── ChartTitle.kt
│ │ ├── MainActivity.kt
│ │ ├── bars
│ │ ├── GroupedBarChartExample.kt
│ │ ├── HistogramChartExample.kt
│ │ ├── SimpleBarChartExample.kt
│ │ ├── StackedBarChartExample.kt
│ │ └── WaterfallChartExample.kt
│ │ ├── buble
│ │ └── BubbleChart.kt
│ │ ├── gantt
│ │ └── GanntChartDemo.kt
│ │ ├── githubgraph
│ │ └── GithubGraph.kt
│ │ ├── line
│ │ ├── GroupedLineChartExample.kt
│ │ ├── ScatterPlotChartExample.kt
│ │ ├── SimpleLineChartExample.kt
│ │ └── StackedLineChartExample.kt
│ │ ├── manager
│ │ └── ChartThemeManager.kt
│ │ ├── pie
│ │ └── PieChartExample.kt
│ │ ├── radar
│ │ └── RadarChart.kt
│ │ └── ui
│ │ └── theme
│ │ ├── Color.kt
│ │ ├── Theme.kt
│ │ └── Type.kt
│ └── res
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── ic_launcher_foreground.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── baselineprofile-app
├── .gitignore
├── api
│ └── baselineprofile-app.api
├── build.gradle.kts
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── kotlin
│ │ └── io
│ │ │ └── androidpoet
│ │ │ └── drafter
│ │ │ └── baselineprofile
│ │ │ └── app
│ │ │ ├── ChartContainer.kt
│ │ │ ├── ChartTitle.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── bars
│ │ │ ├── GroupedBarChartExample.kt
│ │ │ ├── HistogramChartExample.kt
│ │ │ ├── SimpleBarChartExample.kt
│ │ │ ├── StackedBarChartExample.kt
│ │ │ └── WaterfallChartExample.kt
│ │ │ ├── buble
│ │ │ └── BubbleChart.kt
│ │ │ ├── gantt
│ │ │ └── GanntChartDemo.kt
│ │ │ ├── githubgraph
│ │ │ └── GithubGraph.kt
│ │ │ ├── line
│ │ │ ├── GroupedLineChartExample.kt
│ │ │ ├── ScatterPlotChartExample.kt
│ │ │ ├── SimpleLineChartExample.kt
│ │ │ └── StackedLineChartExample.kt
│ │ │ ├── manager
│ │ │ └── ChartThemeManager.kt
│ │ │ ├── pie
│ │ │ └── PieChartExample.kt
│ │ │ ├── radar
│ │ │ └── RadarChart.kt
│ │ │ └── ui
│ │ │ └── theme
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ └── release
│ └── generated
│ └── baselineProfiles
│ └── baseline-prof.txt
├── baselineprofile
├── .gitignore
├── build.gradle.kts
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── kotlin
│ └── io
│ └── androidpoet
│ └── drafter
│ └── baselineprofile
│ └── BaselineProfileGenerator.kt
├── build.gradle.kts
├── buildSrc
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── io
│ └── androidpoet
│ └── drafter
│ └── Configuration.kt
├── chartsx.mp4
├── drafter
├── .gitignore
├── api
│ ├── android
│ │ └── drafter.api
│ └── desktop
│ │ └── drafter.api
├── build.gradle.kts
└── src
│ └── commonMain
│ ├── baseline-prof.txt
│ ├── kotlin
│ └── io
│ │ └── androidpoet
│ │ └── drafter
│ │ ├── bars
│ │ ├── BarChart.kt
│ │ ├── BarChartDataRenderer.kt
│ │ ├── model
│ │ │ └── BarChartModel.kt
│ │ └── renderer
│ │ │ ├── BarChartRenderer.kt
│ │ │ ├── GroupedBarChartRenderer.kt
│ │ │ ├── HistogramRenderer.kt
│ │ │ ├── StackedBarChartRenderer.kt
│ │ │ └── WaterfallChartRenderer.kt
│ │ ├── buble
│ │ ├── BarChartRenderer.kt
│ │ ├── BubbleChart.kt
│ │ ├── BubbleChartData.kt
│ │ └── BubbleChartDataRenderer.kt
│ │ ├── gant
│ │ ├── GantChart.kt
│ │ ├── GantChartData.kt
│ │ └── GanttChartRenderer.kt
│ │ ├── heatmap
│ │ ├── HeatMapData.kt
│ │ ├── Heatmap.kt
│ │ └── HeatmapDataRenderer.kt
│ │ ├── lines
│ │ ├── LineChart.kt
│ │ ├── LineChartDataRenderer.kt
│ │ ├── model
│ │ │ └── LineChartData.kt
│ │ └── renderer
│ │ │ ├── GroupedLineChartRenderer.kt
│ │ │ ├── LineChartRenderer.kt
│ │ │ └── StackedLineChartRenderer.kt
│ │ ├── pie
│ │ ├── PieChart.kt
│ │ ├── model
│ │ │ └── PieChartData.kt
│ │ └── renderer
│ │ │ ├── DonutChartRenderer.kt
│ │ │ ├── PieChartDataRenderer.kt
│ │ │ └── PieChartRenderer.kt
│ │ ├── popup
│ │ └── Tooltip.kt
│ │ ├── radar
│ │ ├── RadarChart.kt
│ │ ├── RadarChartDataRenderer.kt
│ │ ├── model
│ │ │ └── RadarChartData.kt
│ │ └── renderer
│ │ │ └── RadarChartRenderer.kt
│ │ └── scatterplot
│ │ ├── ScatterPlotChart.kt
│ │ ├── ScatterPlotChartRenderer.kt
│ │ └── model
│ │ └── ScatterPlotData.kt
│ └── resources
│ └── files
│ └── countries.json
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── kotlin-js-store
└── yarn.lock
├── renovate.json
├── scripts
└── publish-module.gradle.kts
├── settings.gradle.kts
└── spotless
├── copyright.kt
├── copyright.kts
└── copyright.xml
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 | [*]
3 | # Most of the standard properties are supported
4 | indent_size=2
5 | max_line_length=100
6 |
7 | ktlint_standard_function-naming = disabled
8 | ktlint_standard_property-naming = disabled
9 | ktlint_standard_filename = disabled
10 | ktlint_standard_no-empty-file = disabled
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Lines starting with '#' are comments.
2 | # Each line is a file pattern followed by one or more owners.
3 |
4 | # More details are here: https://help.github.com/articles/about-codeowners/
5 |
6 | # The '*' pattern is global owners.
7 | # Not adding in this PR, but I'd like to try adding a global owner set with the entire team.
8 | # One interpretation of their docs is that global owners are added only if not removed
9 | # by a more local rule.
10 |
11 | # Order is important. The last matching pattern has the most precedence.
12 | # The folders are ordered as follows:
13 |
14 | # In each subsection folders are ordered first by depth, then alphabetically.
15 | # This should make it easy to add new rules without breaking existing ones.
16 | * @androidpoet
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: androidpoet
2 | custom: ["https://www.buymeacoffee.com/androidpoet"]
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Something is crashing or not working as intended
4 |
5 | ---
6 |
7 | **Please complete the following information:**
8 | - Library Version [e.g. v1.0.0]
9 | - Affected Device(s) [e.g. Samsung Galaxy s10 with Android 9.0]
10 |
11 | **Describe the Bug:**
12 |
13 | Add a clear description about the problem.
14 |
15 | **Expected Behavior:**
16 |
17 | A clear description of what you expected to happen.
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem?**
8 |
9 | A clear and concise description of what the problem is.
10 |
11 | **Describe the solution you'd like:**
12 |
13 | A clear and concise description of what you want to happen.
14 |
15 | **Describe alternatives you've considered:**
16 |
17 | A clear description of any alternative solutions you've considered.
18 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Guidelines
2 | Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue.
3 |
4 | ### Types of changes
5 | What types of changes does your code introduce?
6 |
7 | - [ ] Bugfix (non-breaking change which fixes an issue)
8 | - [ ] New feature (non-breaking change which adds functionality)
9 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
10 |
11 | ### Preparing a pull request for review
12 | Ensure your change is properly formatted by running:
13 |
14 | ```gradle
15 | $ ./gradlew spotlessApply
16 | ```
17 |
18 | Please correct any failures before requesting a review.
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | lint:
11 | name: Spotless check
12 | runs-on: macos-latest
13 | steps:
14 | - name: Check out code
15 | uses: actions/checkout@v2
16 | - name: Set up JDK
17 | uses: actions/setup-java@v1
18 | with:
19 | distribution: zulu
20 | java-version: 17
21 | - name: spotless
22 | run: ./gradlew spotlessCheck
23 |
24 | api_check:
25 | name: API check
26 | runs-on: macos-latest
27 | steps:
28 | - name: Check out code
29 | uses: actions/checkout@v2
30 | - name: Set up JDK
31 | uses: actions/setup-java@v1
32 | with:
33 | distribution: zulu
34 | java-version: 17
35 | - name: API check
36 | run: ./gradlew apiCheck
37 |
38 | build:
39 | runs-on: macos-latest
40 | steps:
41 | - uses: actions/checkout@v2
42 |
43 | - name: set up JDK
44 | uses: actions/setup-java@v1
45 | with:
46 | distribution: zulu
47 | java-version: 17
48 |
49 | - name: Cache Gradle and wrapper
50 | uses: actions/cache@v2
51 | with:
52 | path: |
53 | ~/.gradle/caches
54 | ~/.gradle/wrapper
55 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
56 | restore-keys: |
57 | ${{ runner.os }}-gradle-
58 |
59 | - name: Make Gradle executable
60 | run: chmod +x ./gradlew
61 |
62 | - name: Build with Gradle
63 | run: |
64 | ./gradlew --scan --stacktrace \
65 | assemble -x :baselineprofile:pixel6api31Setup -x :baselineprofile:pixel6api31NonMinifiedReleaseAndroidTest -x :baselineprofile:collectNonMinifiedReleaseBaselineProfile
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | release:
5 | types: [ released ]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | publish:
10 | name: Snapshot build and publish
11 | runs-on: macos-latest
12 | steps:
13 | - name: Check out code
14 | uses: actions/checkout@v3.1.0
15 |
16 | - name: Set up JDK 17
17 | uses: actions/setup-java@v3.5.1
18 | with:
19 | distribution: 'zulu'
20 | java-version: 17
21 |
22 | - name: Grant Permission to Execute Gradle
23 | run: chmod +x gradlew
24 |
25 | - name: Release build
26 | run: ./gradlew assemble --scan -x :baselineprofile:pixel6api31Setup -x :baselineprofile:pixel6api31NonMinifiedReleaseAndroidTest -x :baselineprofile:collectNonMinifiedReleaseBaselineProfile
27 |
28 | - name: Publish to MavenCentral
29 | run: |
30 | ./gradlew publishAllPublicationsToMavenCentral --no-configuration-cache
31 | env:
32 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.OSSRH_USERNAME }}
33 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.OSSRH_PASSWORD }}
34 | ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }}
35 | ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}
36 | ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }}
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Kotlin class files
12 | .kotlin
13 |
14 | # Generated files
15 | bin/
16 | gen/
17 | out/
18 |
19 | # Gradle files
20 | /.idea
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | # Proguard folder generated by Eclipse
28 | proguard/
29 |
30 | # Log Files
31 | *.log
32 |
33 | # Android Studio Navigation editor temp files
34 | .navigation/
35 |
36 | # Android Studio captures folder
37 | captures/
38 |
39 | # Intellij
40 | *.iml
41 | .idea/workspace.xml
42 | .idea/tasks.xml
43 | .idea/gradle.xml
44 | .idea/dictionaries
45 | .idea/libraries
46 | app/.idea/
47 |
48 | # Mac
49 | *.DS_Store
50 |
51 | # Keystore files
52 | *.jks
53 |
54 | # External native build folder generated in Android Studio 2.2 and later
55 | .externalNativeBuild
56 |
57 | # Google Services (e.g. APIs or Firebase)
58 | google-services.json
59 |
60 | # Freeline
61 | freeline.py
62 | freeline/
63 | freeline_project_description.json
64 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to contribute
2 | We'd love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow.
3 |
4 | ## Preparing a pull request for review
5 | Ensure your change is properly formatted by running:
6 |
7 | ```gradle
8 | ./gradlew spotlessApply
9 | ```
10 |
11 | Then dump binary API of this library that is public in sense of Kotlin visibilities and ensures that the public binary API wasn't changed in a way that make this change binary incompatible.
12 |
13 | ```gradle
14 | ./gradlew apiDump
15 | ```
16 |
17 | Please correct any failures before requesting a review.
18 |
19 | ## Code reviews
20 | All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult [GitHub Help](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) for more information on using pull requests.
21 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | import io.androidpoet.drafter.Configuration
3 |
4 | @Suppress("DSL_SCOPE_VIOLATION")
5 | plugins {
6 | id(
7 | libs.plugins.android.application
8 | .get()
9 | .pluginId,
10 | )
11 | id(
12 | libs.plugins.kotlin.android
13 | .get()
14 | .pluginId,
15 | )
16 | id(
17 | libs.plugins.compose.compiler
18 | .get()
19 | .pluginId,
20 | )
21 | }
22 |
23 | android {
24 | compileSdk = Configuration.compileSdk
25 | namespace = "io.androidpoet.drafterdemo"
26 | defaultConfig {
27 | applicationId = "io.androidpoet.drafterdemo"
28 | minSdk = Configuration.minSdk
29 | targetSdk = Configuration.targetSdk
30 | versionCode = Configuration.versionCode
31 | versionName = Configuration.versionName
32 | }
33 |
34 | compileOptions {
35 | sourceCompatibility = JavaVersion.VERSION_11
36 | targetCompatibility = JavaVersion.VERSION_11
37 | }
38 |
39 | kotlinOptions {
40 | jvmTarget = libs.versions.jvmTarget.get()
41 | }
42 |
43 | buildFeatures {
44 | compose = true
45 | buildConfig = true
46 | }
47 |
48 | packaging {
49 | resources {
50 | excludes.add("/META-INF/{AL2.0,LGPL2.1}")
51 | }
52 | }
53 |
54 | lint {
55 | abortOnError = false
56 | }
57 | buildTypes {
58 | getByName("release") {
59 | signingConfig = signingConfigs.getByName("debug")
60 | }
61 | }
62 | }
63 |
64 | dependencies {
65 | implementation(platform(libs.androidx.compose.bom))
66 | implementation(libs.androidx.activity.compose)
67 | implementation(libs.androidx.compose.ui)
68 | implementation(libs.androidx.compose.ui.tooling)
69 | implementation(libs.androidx.compose.foundation)
70 | implementation(libs.androidx.compose.runtime)
71 | implementation(libs.androidx.compose.material)
72 | implementation(libs.androidx.compose.material3)
73 | implementation(libs.kotlinx.datetime)
74 | implementation(project(":drafter"))
75 | }
76 | task("testClasses") {}
77 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
21 |
31 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/ChartContainer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo
17 |
18 | import androidx.compose.foundation.layout.Box
19 | import androidx.compose.foundation.layout.fillMaxWidth
20 | import androidx.compose.foundation.layout.height
21 | import androidx.compose.foundation.layout.padding
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Alignment
24 | import androidx.compose.ui.Modifier
25 | import androidx.compose.ui.unit.dp
26 |
27 | @Composable
28 | fun ChartContainer(
29 | modifier: Modifier = Modifier,
30 | content: @Composable () -> Unit,
31 | ) {
32 | Box(
33 | modifier =
34 | modifier
35 | .fillMaxWidth()
36 | .height(200.dp)
37 | .padding(horizontal = 16.dp),
38 | contentAlignment = Alignment.Center,
39 | ) {
40 | content()
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/ChartTitle.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.padding
20 | import androidx.compose.material3.MaterialTheme
21 | import androidx.compose.material3.Text
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Modifier
24 | import androidx.compose.ui.text.style.TextAlign
25 | import androidx.compose.ui.unit.dp
26 |
27 | @Composable
28 | fun ChartTitle(
29 | text: String,
30 | modifier: Modifier = Modifier,
31 | ) {
32 | Text(
33 | text = text,
34 | modifier =
35 | modifier
36 | .padding(horizontal = 16.dp)
37 | .fillMaxWidth(),
38 | style = MaterialTheme.typography.titleLarge,
39 | textAlign = TextAlign.Center,
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/bars/GroupedBarChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.GroupedBarChartData
26 | import io.androidpoet.drafter.bars.renderer.GroupedBarChartRenderer
27 |
28 | private fun getBarChartRenderer() =
29 | GroupedBarChartRenderer(
30 | GroupedBarChartData(
31 | labelsList = listOf("2020", "2021", "2022"),
32 | itemNames = listOf("Product A", "Product B", "Product C"),
33 | groupedValues =
34 | listOf(
35 | listOf(10f, 20f, 15f), // 2020
36 | listOf(25f, 5f, 30f), // 2021
37 | listOf(12f, 28f, 10f), // 2022
38 | ),
39 | colors = listOf(Color.Red, Color.Green, Color.Blue),
40 | ),
41 | )
42 |
43 | @Composable
44 | fun GroupedBarChartExample(
45 | colors: List,
46 | modifier: Modifier = Modifier,
47 | ) {
48 | BarChart(
49 | renderer = getBarChartRenderer(),
50 | modifier =
51 | Modifier
52 | .height(300.dp)
53 | .fillMaxWidth(),
54 | animate = true,
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/bars/HistogramChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.renderer.HistogramRenderer
26 |
27 | private fun getHistogramData() = listOf(1f, 2f, 2f, 3f, 3f, 3f, 4f, 4f, 5f, 5f, 5f, 5f)
28 |
29 | private fun getHistogramRenderer() =
30 | HistogramRenderer(
31 | dataPoints = getHistogramData(),
32 | binCount = 5,
33 | color = Color.Blue,
34 | )
35 |
36 | @Composable
37 | fun HistogramChartExample(
38 | modifier: Modifier = Modifier,
39 | animate: Boolean = true,
40 | ) {
41 | BarChart(
42 | renderer = getHistogramRenderer(),
43 | modifier =
44 | modifier
45 | .height(300.dp)
46 | .fillMaxWidth(),
47 | animate = animate,
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/bars/SimpleBarChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.SimpleBarChartData
26 | import io.androidpoet.drafter.bars.renderer.BarChartRenderer
27 |
28 | private fun getBarChartData(colors: List) =
29 | SimpleBarChartData(
30 | labelsList = listOf("Jan", "Feb", "Mar", "Apr"),
31 | values = listOf(10f, 30f, 15f, 45f),
32 | colors = colors,
33 | )
34 |
35 | private fun getSimpleBarChartRenderer(colors: List) =
36 | BarChartRenderer(getBarChartData(colors = colors))
37 |
38 | @Composable
39 | fun SimpleBarChartExample(
40 | colors: List,
41 | modifier: Modifier = Modifier,
42 | ) {
43 | BarChart(
44 | renderer = getSimpleBarChartRenderer(colors = colors),
45 | modifier =
46 | modifier
47 | .height(300.dp)
48 | .fillMaxWidth(),
49 | animate = true,
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/bars/StackedBarChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.StackedBarChartData
26 | import io.androidpoet.drafter.bars.renderer.StackedBarChartRenderer
27 |
28 | private fun getStackedBarChartData(colors: List) =
29 | StackedBarChartData(
30 | labelsList = listOf("Q1", "Q2", "Q3"),
31 | stacks =
32 | listOf(
33 | listOf(10f, 15f, 5f), // Q1
34 | listOf(8f, 12f, 20f), // Q2
35 | listOf(18f, 10f, 15f), // Q3
36 | ),
37 | colors = colors,
38 | )
39 |
40 | private fun getStackedBarChartRenderer(colors: List) =
41 | StackedBarChartRenderer(getStackedBarChartData(colors = colors))
42 |
43 | @Composable
44 | fun StackedBarChartExample(
45 | colors: List,
46 | modifier: Modifier = Modifier,
47 | ) {
48 | BarChart(
49 | renderer = getStackedBarChartRenderer(colors = colors),
50 | modifier =
51 | modifier
52 | .height(300.dp)
53 | .fillMaxWidth(),
54 | animate = true,
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/bars/WaterfallChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.WaterfallChartData
26 | import io.androidpoet.drafter.bars.renderer.WaterfallChartRenderer
27 |
28 | private fun getWaterfallChartRenderer(colors: List) =
29 | WaterfallChartRenderer(
30 | WaterfallChartData(
31 | labelsList = listOf("Start", "Revenue", "Cost", "Profit"),
32 | values = listOf(+50f, -20f, +30f), // Changes from 'Start'
33 | colors = colors,
34 | initialValue = 100f, // Start from 100
35 | ),
36 | )
37 |
38 | @Composable
39 | fun WaterfallChartExample(
40 | colors: List,
41 | modifier: Modifier = Modifier,
42 | ) {
43 | BarChart(
44 | renderer = getWaterfallChartRenderer(colors = colors),
45 | modifier =
46 | modifier
47 | .height(300.dp)
48 | .fillMaxWidth(),
49 | animate = true,
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/buble/BubbleChart.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.buble
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.buble.BubbleChart
25 | import io.androidpoet.drafter.buble.BubbleChartData
26 | import io.androidpoet.drafter.buble.SimpleBubbleChartDataRenderer
27 |
28 | private fun getBubbleChartData(colors: List) =
29 | BubbleChartData(
30 | series =
31 | listOf(
32 | listOf(
33 | BubbleChartData.BubbleData(10f, 26f, 30f, colors[0]),
34 | BubbleChartData.BubbleData(26f, 30f, 60f, colors[0]),
35 | BubbleChartData.BubbleData(26f, 46f, 45f, colors[0]),
36 | ),
37 | listOf(
38 | BubbleChartData.BubbleData(14f, 15f, 30f, colors[1]),
39 | BubbleChartData.BubbleData(22f, 36f, 45f, colors[1]),
40 | BubbleChartData.BubbleData(90f, 57f, 75f, colors[1]),
41 | ),
42 | listOf(
43 | BubbleChartData.BubbleData(8f, 9f, 90f, colors[2]),
44 | BubbleChartData.BubbleData(20f, 57f, 45f, colors[2]),
45 | BubbleChartData.BubbleData(40f, 50f, 60f, colors[2]),
46 | ),
47 | listOf(
48 | BubbleChartData.BubbleData(8f, 20f, 22.5f, colors[3]),
49 | BubbleChartData.BubbleData(12f, 30f, 30f, colors[3]),
50 | BubbleChartData.BubbleData(30f, 40f, 45f, colors[3]),
51 | ),
52 | ),
53 | )
54 |
55 | private fun getBubbleChartRenderer(colors: List) =
56 | SimpleBubbleChartDataRenderer(getBubbleChartData(colors = colors))
57 |
58 | @Composable
59 | fun BubbleChartExample(
60 | colors: List,
61 | modifier: Modifier = Modifier,
62 | ) {
63 | BubbleChart(
64 | renderer = getBubbleChartRenderer(colors = colors),
65 | modifier =
66 | modifier
67 | .height(300.dp)
68 | .fillMaxWidth(),
69 | )
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/gantt/GanntChartDemo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.gantt
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.gant.GanttChart
25 | import io.androidpoet.drafter.gant.GanttChartData
26 | import io.androidpoet.drafter.gant.GanttChartRenderer
27 | import io.androidpoet.drafter.gant.GanttTask
28 |
29 | private fun getGanttChartRenderer(colors: List) =
30 | GanttChartRenderer(
31 | GanttChartData(
32 | taskColors = colors,
33 | tasks =
34 | listOf(
35 | GanttTask("Planning", 0f, 2f),
36 | GanttTask("Design", 2f, 2f),
37 | GanttTask("Development", 4f, 3f),
38 | GanttTask("Testing", 7f, 2f),
39 | GanttTask("Deployment", 9f, 1f),
40 | ),
41 | ),
42 | )
43 |
44 | @Composable
45 | fun GanttChartExample(
46 | colors: List,
47 | modifier: Modifier = Modifier,
48 | ) {
49 | GanttChart(
50 | renderer = getGanttChartRenderer(colors = colors),
51 | modifier =
52 | modifier
53 | .height(300.dp)
54 | .fillMaxWidth(),
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/githubgraph/GithubGraph.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.githubgraph
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.heatmap.ContributionData
25 | import io.androidpoet.drafter.heatmap.ContributionHeatmapData
26 | import io.androidpoet.drafter.heatmap.Heatmap
27 | import io.androidpoet.drafter.heatmap.HeatmapRenderer
28 | import kotlinx.datetime.Clock
29 | import kotlin.random.Random
30 | import kotlin.time.Duration.Companion.days
31 |
32 | private fun getHeatmapRenderer(color: Color) =
33 | HeatmapRenderer(
34 | ContributionHeatmapData(
35 | baseColor = color,
36 | contributions =
37 | buildList {
38 | val now = Clock.System.now()
39 | repeat(365) { day ->
40 | val date = now.minus(day.days)
41 | val count = if (Random.nextFloat() > 0.6f) Random.nextInt(1, 15) else 0
42 | add(ContributionData(date, count))
43 | }
44 | },
45 | ),
46 | )
47 |
48 | @Composable
49 | fun GithubGraph(
50 | color: Color,
51 | modifier: Modifier = Modifier,
52 | ) {
53 | Heatmap(
54 | renderer = getHeatmapRenderer(color = color),
55 | modifier =
56 | modifier
57 | .height(300.dp)
58 | .fillMaxWidth(),
59 | )
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/line/GroupedLineChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.line
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.lines.LineChart
25 | import io.androidpoet.drafter.lines.model.GroupedLineChartData
26 | import io.androidpoet.drafter.lines.renderer.GroupedLineChartRenderer
27 | import io.androidpoet.drafterdemo.ChartContainer
28 |
29 | private fun getGroupedLineChartData(colors: List) =
30 | GroupedLineChartData(
31 | labels = listOf("Q1", "Q2", "Q3", "Q4"),
32 | itemNames = listOf("Product A", "Product B"),
33 | groupedValues =
34 | listOf(
35 | listOf(10f, 15f),
36 | listOf(20f, 25f),
37 | listOf(15f, 10f),
38 | listOf(25f, 20f),
39 | ),
40 | colors = colors,
41 | )
42 |
43 | private fun getGroupedLineChartRenderer(colors: List) =
44 | GroupedLineChartRenderer(getGroupedLineChartData(colors = colors))
45 |
46 | @Composable
47 | fun GroupedLineChartExample(
48 | colors: List,
49 | modifier: Modifier = Modifier,
50 | ) {
51 | ChartContainer {
52 | LineChart(
53 | renderer = getGroupedLineChartRenderer(colors = colors),
54 | modifier =
55 | modifier
56 | .height(300.dp)
57 | .fillMaxWidth(),
58 | )
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/line/ScatterPlotChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.line
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.scatterplot.ScatterPlot
25 | import io.androidpoet.drafter.scatterplot.SimpleScatterPlotRenderer
26 | import io.androidpoet.drafter.scatterplot.model.ScatterPlotData
27 | import kotlin.math.roundToInt
28 | import kotlin.random.Random
29 |
30 | private fun getScatterPlotRenderer(colors: List) =
31 | SimpleScatterPlotRenderer(
32 | ScatterPlotData(
33 | points =
34 | List(30) {
35 | Pair(
36 | (Random.nextFloat() * 10).roundToInt() / 10f,
37 | (Random.nextFloat() * 10).roundToInt() / 10f,
38 | )
39 | },
40 | pointColors =
41 | List(30) {
42 | if (colors.isNotEmpty()) colors[it % colors.size] else Color.Gray
43 | },
44 | ),
45 | )
46 |
47 | @Composable
48 | fun ScatterPlotChartExample(
49 | colors: List,
50 | modifier: Modifier = Modifier,
51 | ) {
52 | ScatterPlot(
53 | modifier =
54 | Modifier
55 | .height(300.dp)
56 | .fillMaxWidth(),
57 | renderer = getScatterPlotRenderer(colors = colors),
58 | )
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/line/SimpleLineChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.line
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.lines.LineChart
25 | import io.androidpoet.drafter.lines.model.SimpleLineChartData
26 | import io.androidpoet.drafter.lines.renderer.LineChartRenderer
27 |
28 | private fun getLineChartRenderer(colors: List) =
29 | LineChartRenderer(
30 | SimpleLineChartData(
31 | labels = listOf("A", "B", "C", "D"),
32 | values = listOf(10f, 20f, 15f, 25f),
33 | color = colors.first(),
34 | ),
35 | )
36 |
37 | @Composable
38 | fun SimpleLineChartExample(
39 | colors: List,
40 | modifier: Modifier = Modifier,
41 | ) {
42 | LineChart(
43 | renderer = getLineChartRenderer(colors = colors),
44 | modifier =
45 | modifier
46 | .height(300.dp)
47 | .fillMaxWidth(),
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/line/StackedLineChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.line
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.lines.LineChart
25 | import io.androidpoet.drafter.lines.model.StackedLineChartData
26 | import io.androidpoet.drafter.lines.renderer.StackedLineChartRenderer
27 | import io.androidpoet.drafterdemo.ChartContainer
28 |
29 | private fun getStackedLineChartRenderer(colors: List) =
30 | StackedLineChartRenderer(
31 | StackedLineChartData(
32 | labels = listOf("Jan", "Feb", "Mar", "Apr"),
33 | stacks =
34 | listOf(
35 | listOf(5f, 5f, 2f),
36 | listOf(7f, 3f, 4f),
37 | listOf(6f, 4f, 3f),
38 | listOf(8f, 2f, 5f),
39 | ),
40 | colors = colors,
41 | ),
42 | )
43 |
44 | @Composable
45 | fun StackedLineChartExample(
46 | colors: List,
47 | modifier: Modifier = Modifier,
48 | ) {
49 | ChartContainer {
50 | LineChart(
51 | renderer = getStackedLineChartRenderer(colors = colors),
52 | modifier =
53 | modifier
54 | .height(300.dp)
55 | .fillMaxWidth(),
56 | )
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/manager/ChartThemeManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.manager
17 |
18 | import androidx.compose.runtime.State
19 | import androidx.compose.runtime.mutableStateOf
20 | import androidx.compose.ui.graphics.Color
21 |
22 | object ChartThemeManager {
23 | enum class ColorTheme {
24 | MATERIAL,
25 | MODERN,
26 | NATURE,
27 | PROFESSIONAL,
28 | }
29 |
30 | private val palettes =
31 | mapOf(
32 | ColorTheme.MATERIAL to
33 | listOf(
34 | Color(0xFF2196F3), // Primary Blue
35 | Color(0xFFFF9800), // Orange
36 | Color(0xFF4CAF50), // Green
37 | Color(0xFFF44336), // Red
38 | Color(0xFF9C27B0), // Purple
39 | Color(0xFF795548), // Brown
40 | Color(0xFF009688), // Teal
41 | Color(0xFFE91E63), // Pink
42 | ),
43 | ColorTheme.MODERN to
44 | listOf(
45 | Color(0xFF7E57C2), // Purple
46 | Color(0xFF26A69A), // Teal
47 | Color(0xFFFF7043), // Coral
48 | Color(0xFF66BB6A), // Light Green
49 | Color(0xFF5C6BC0), // Indigo
50 | Color(0xFFFFCA28), // Amber
51 | Color(0xFF42A5F5), // Light Blue
52 | Color(0xFFEC407A), // Pink
53 | ),
54 | ColorTheme.NATURE to
55 | listOf(
56 | Color(0xFF66BB6A), // Green
57 | Color(0xFF42A5F5), // Sky Blue
58 | Color(0xFFFFB74D), // Light Orange
59 | Color(0xFF8D6E63), // Brown
60 | Color(0xFF26A69A), // Sea Green
61 | Color(0xFFFFCC80), // Pale Orange
62 | Color(0xFF81C784), // Light Green
63 | Color(0xFF7986CB), // Blue Grey
64 | ),
65 | ColorTheme.PROFESSIONAL to
66 | listOf(
67 | Color(0xFF5C6BC0), // Indigo
68 | Color(0xFF8D6E63), // Brown
69 | Color(0xFF26A69A), // Teal
70 | Color(0xFF78909C), // Blue Grey
71 | Color(0xFF7E57C2), // Deep Purple
72 | Color(0xFF66BB6A), // Green
73 | Color(0xFF29B6F6), // Light Blue
74 | Color(0xFFBDBDBD), // Grey
75 | ),
76 | )
77 |
78 | private val githubColors =
79 | listOf(
80 | Color(0xFF0E4429), // Darkest
81 | Color(0xFF006D32), // Dark
82 | Color(0xFF26A641), // Medium
83 | Color(0xFF39D353), // Light
84 | )
85 |
86 | private fun getFullPalette(theme: ColorTheme): List =
87 | palettes[theme] ?: palettes[ColorTheme.MATERIAL]!!
88 |
89 | private val _currentTheme = mutableStateOf(ColorTheme.MATERIAL)
90 | private val _currentFullPalette = mutableStateOf(getFullPalette(ColorTheme.MATERIAL))
91 | val currentTheme: State = _currentTheme
92 | val palette: State> = _currentFullPalette
93 |
94 | fun setTheme(theme: ColorTheme) {
95 | _currentTheme.value = theme
96 | _currentFullPalette.value = getFullPalette(theme)
97 | }
98 |
99 | fun getGithubColors() = githubColors
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/pie/PieChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.pie
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.pie.PieChart
25 | import io.androidpoet.drafter.pie.model.PieChartData
26 | import io.androidpoet.drafter.pie.renderer.DonutChartRenderer
27 | import io.androidpoet.drafter.pie.renderer.PieChartRenderer
28 |
29 | private fun getPieChartRenderer(colors: List) =
30 | PieChartRenderer(
31 | PieChartData(
32 | slices =
33 | listOf(
34 | PieChartData.Slice(value = 40f, color = colors[0], label = "Red"),
35 | PieChartData.Slice(value = 30f, color = colors[1], label = "Green"),
36 | PieChartData.Slice(value = 20f, color = colors[2], label = "Blue"),
37 | PieChartData.Slice(value = 10f, color = colors[3], label = "Purple"),
38 | ),
39 | ),
40 | )
41 |
42 | private fun getDonutPieChartRenderer(colors: List) =
43 | DonutChartRenderer(
44 | PieChartData(
45 | slices =
46 | listOf(
47 | PieChartData.Slice(value = 40f, color = colors[0], label = "Red"),
48 | PieChartData.Slice(value = 30f, color = colors[1], label = "Green"),
49 | PieChartData.Slice(value = 20f, color = colors[2], label = "Blue"),
50 | PieChartData.Slice(value = 10f, color = colors[3], label = "Purple"),
51 | ),
52 | ),
53 | )
54 |
55 | @Composable
56 | fun PieChartExample(
57 | colors: List,
58 | modifier: Modifier = Modifier,
59 | ) {
60 | PieChart(
61 | renderer = getPieChartRenderer(colors = colors),
62 | modifier =
63 | modifier
64 | .height(300.dp).fillMaxWidth(),
65 | animate = true,
66 | )
67 | }
68 |
69 | @Composable
70 | fun DonutChartExample(
71 | colors: List,
72 | modifier: Modifier = Modifier,
73 | ) {
74 | PieChart(
75 | renderer = getDonutPieChartRenderer(colors = colors),
76 | modifier =
77 | modifier
78 | .height(300.dp)
79 | .fillMaxWidth(),
80 | animate = true,
81 | )
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/radar/RadarChart.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.radar
17 |
18 | import androidx.compose.foundation.isSystemInDarkTheme
19 | import androidx.compose.foundation.layout.fillMaxWidth
20 | import androidx.compose.foundation.layout.height
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.ui.Modifier
23 | import androidx.compose.ui.graphics.Color
24 | import androidx.compose.ui.unit.dp
25 | import io.androidpoet.drafter.radar.RadarChart
26 | import io.androidpoet.drafter.radar.model.RadarChartData
27 | import io.androidpoet.drafter.radar.renderer.RadarChartRenderer
28 |
29 | private fun getRadarRenderer(colors: List) =
30 | RadarChartRenderer(
31 | data =
32 | listOf(
33 | RadarChartData(
34 | mapOf(
35 | "Execution" to 0.8f,
36 | "Landing" to 0.6f,
37 | "Difficulty" to 0.9f,
38 | "Style" to 0.7f,
39 | "Creativity" to 0.85f,
40 | ),
41 | ),
42 | ),
43 | colors = colors,
44 | )
45 |
46 | @Composable
47 | fun RadarChartExample(
48 | colors: List,
49 | modifier: Modifier = Modifier,
50 | ) {
51 | RadarChart(
52 | modifier =
53 | modifier
54 | .height(300.dp)
55 | .fillMaxWidth(),
56 | renderer = getRadarRenderer(colors),
57 | isSystemInDarkTheme = isSystemInDarkTheme(),
58 | )
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.ui.theme
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | val Purple80 = Color(0xFFD0BCFF)
21 | val PurpleGrey80 = Color(0xFFCCC2DC)
22 | val Pink80 = Color(0xFFEFB8C8)
23 |
24 | val Purple40 = Color(0xFF6650a4)
25 | val PurpleGrey40 = Color(0xFF625b71)
26 | val Pink40 = Color(0xFF7D5260)
27 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.ui.theme
17 |
18 | import android.app.Activity
19 | import android.os.Build
20 | import androidx.compose.foundation.isSystemInDarkTheme
21 | import androidx.compose.material3.MaterialTheme
22 | import androidx.compose.material3.darkColorScheme
23 | import androidx.compose.material3.dynamicDarkColorScheme
24 | import androidx.compose.material3.dynamicLightColorScheme
25 | import androidx.compose.material3.lightColorScheme
26 | import androidx.compose.runtime.Composable
27 | import androidx.compose.runtime.SideEffect
28 | import androidx.compose.ui.graphics.toArgb
29 | import androidx.compose.ui.platform.LocalContext
30 | import androidx.compose.ui.platform.LocalView
31 | import androidx.core.view.WindowCompat
32 |
33 | private val DarkColorScheme =
34 | darkColorScheme(
35 | primary = Purple80,
36 | secondary = PurpleGrey80,
37 | tertiary = Pink80,
38 | )
39 |
40 | private val LightColorScheme =
41 | lightColorScheme(
42 | primary = Purple40,
43 | secondary = PurpleGrey40,
44 | tertiary = Pink40,
45 | /* Other default colors to override
46 | background = Color(0xFFFFFBFE),
47 | surface = Color(0xFFFFFBFE),
48 | onPrimary = Color.White,
49 | onSecondary = Color.White,
50 | onTertiary = Color.White,
51 | onBackground = Color(0xFF1C1B1F),
52 | onSurface = Color(0xFF1C1B1F),
53 | */
54 | )
55 |
56 | @Composable
57 | fun DrafterDemoTheme(
58 | darkTheme: Boolean = isSystemInDarkTheme(),
59 | dynamicColor: Boolean = true,
60 | content: @Composable () -> Unit,
61 | ) {
62 | val colorScheme =
63 | when {
64 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
65 | val context = LocalContext.current
66 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
67 | }
68 |
69 | darkTheme -> DarkColorScheme
70 | else -> LightColorScheme
71 | }
72 | val view = LocalView.current
73 | if (!view.isInEditMode) {
74 | SideEffect {
75 | val window = (view.context as Activity).window
76 | window.statusBarColor = colorScheme.primary.toArgb()
77 | WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
78 | }
79 | }
80 |
81 | MaterialTheme(
82 | colorScheme = colorScheme,
83 | typography = Typography,
84 | content = content,
85 | )
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/io/androidpoet/drafterdemo/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafterdemo.ui.theme
17 |
18 | import androidx.compose.material3.Typography
19 | import androidx.compose.ui.text.TextStyle
20 | import androidx.compose.ui.text.font.FontFamily
21 | import androidx.compose.ui.text.font.FontWeight
22 | import androidx.compose.ui.unit.sp
23 |
24 | val Typography =
25 | Typography(
26 | bodyLarge =
27 | TextStyle(
28 | fontFamily = FontFamily.Default,
29 | fontWeight = FontWeight.Normal,
30 | fontSize = 16.sp,
31 | lineHeight = 24.sp,
32 | letterSpacing = 0.5.sp,
33 | ),
34 | /* Other default text styles to override
35 | titleLarge = TextStyle(
36 | fontFamily = FontFamily.Default,
37 | fontWeight = FontWeight.Normal,
38 | fontSize = 22.sp,
39 | lineHeight = 28.sp,
40 | letterSpacing = 0.sp
41 | ),
42 | labelSmall = TextStyle(
43 | fontFamily = FontFamily.Default,
44 | fontWeight = FontWeight.Medium,
45 | fontSize = 11.sp,
46 | lineHeight = 16.sp,
47 | letterSpacing = 0.5.sp
48 | )
49 | */
50 | )
51 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
23 |
24 |
25 |
31 |
34 |
37 |
38 |
39 |
40 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #FFBB86FC
19 | #FF6200EE
20 | #FF3700B3
21 | #FF03DAC5
22 | #FF018786
23 | #FF000000
24 | #FFFFFFFF
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | DrafterDemo
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
23 |
24 |
30 |
31 |
--------------------------------------------------------------------------------
/baselineprofile-app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/baselineprofile-app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import io.androidpoet.drafter.Configuration
2 |
3 | @Suppress("DSL_SCOPE_VIOLATION")
4 | plugins {
5 | id(
6 | libs.plugins.android.application
7 | .get()
8 | .pluginId,
9 | )
10 | id(
11 | libs.plugins.kotlin.android
12 | .get()
13 | .pluginId,
14 | )
15 | id(
16 | libs.plugins.compose.compiler
17 | .get()
18 | .pluginId,
19 | )
20 | id(
21 | libs.plugins.baseline.profile
22 | .get()
23 | .pluginId,
24 | )
25 | }
26 |
27 | android {
28 | namespace = "io.androidpoet.drafter.baselineprofile.app"
29 | compileSdk = Configuration.compileSdk
30 |
31 | defaultConfig {
32 | applicationId = "io.androidpoet.drafter.baselineprofile.app"
33 | minSdk = 23
34 | }
35 |
36 | compileOptions {
37 | sourceCompatibility = JavaVersion.VERSION_11
38 | targetCompatibility = JavaVersion.VERSION_11
39 | }
40 |
41 | kotlinOptions {
42 | jvmTarget = libs.versions.jvmTarget.get()
43 | }
44 |
45 | buildFeatures {
46 | compose = true
47 | buildConfig = true
48 | }
49 |
50 | lint {
51 | abortOnError = false
52 | }
53 |
54 | buildTypes {
55 | create("benchmark") {
56 | isDebuggable = true
57 | signingConfig = getByName("debug").signingConfig
58 | matchingFallbacks += listOf("release")
59 | }
60 | }
61 | }
62 |
63 | dependencies {
64 |
65 | implementation(platform(libs.androidx.compose.bom))
66 | implementation(libs.androidx.activity.compose)
67 | implementation(libs.androidx.compose.ui)
68 | implementation(libs.androidx.compose.ui.tooling)
69 | implementation(libs.androidx.compose.foundation)
70 | implementation(libs.androidx.compose.runtime)
71 | implementation(libs.androidx.compose.material3)
72 | implementation(libs.kotlinx.datetime)
73 | implementation(project(":drafter"))
74 | baselineProfile(project(":baselineprofile"))
75 | }
76 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
27 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/ChartContainer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app
17 |
18 | import androidx.compose.foundation.layout.Box
19 | import androidx.compose.foundation.layout.fillMaxWidth
20 | import androidx.compose.foundation.layout.height
21 | import androidx.compose.foundation.layout.padding
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Alignment
24 | import androidx.compose.ui.Modifier
25 | import androidx.compose.ui.unit.dp
26 |
27 | @Composable
28 | fun ChartContainer(
29 | modifier: Modifier = Modifier,
30 | content: @Composable () -> Unit,
31 | ) {
32 | Box(
33 | modifier =
34 | modifier
35 | .fillMaxWidth()
36 | .height(200.dp)
37 | .padding(horizontal = 16.dp),
38 | contentAlignment = Alignment.Center,
39 | ) {
40 | content()
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/ChartTitle.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app
17 |
18 | import androidx.compose.foundation.layout.padding
19 | import androidx.compose.material3.MaterialTheme
20 | import androidx.compose.material3.Text
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.ui.Modifier
23 | import androidx.compose.ui.unit.dp
24 |
25 | @Composable
26 | fun ChartTitle(text: String) {
27 | Text(
28 | text = text,
29 | modifier = Modifier.padding(horizontal = 16.dp),
30 | style = MaterialTheme.typography.titleLarge,
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/bars/GroupedBarChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.GroupedBarChartData
26 | import io.androidpoet.drafter.bars.renderer.GroupedBarChartRenderer
27 |
28 | private fun getBarChartRenderer() =
29 | GroupedBarChartRenderer(
30 | GroupedBarChartData(
31 | labelsList = listOf("2020", "2021", "2022"),
32 | itemNames = listOf("Product A", "Product B", "Product C"),
33 | groupedValues =
34 | listOf(
35 | listOf(10f, 20f, 15f), // 2020
36 | listOf(25f, 5f, 30f), // 2021
37 | listOf(12f, 28f, 10f), // 2022
38 | ),
39 | colors = listOf(Color.Red, Color.Green, Color.Blue),
40 | ),
41 | )
42 |
43 | @Composable
44 | fun GroupedBarChartExample(
45 | colors: List,
46 | modifier: Modifier = Modifier,
47 | ) {
48 | BarChart(
49 | renderer = getBarChartRenderer(),
50 | modifier =
51 | Modifier
52 | .height(300.dp)
53 | .fillMaxWidth(),
54 | animate = true,
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/bars/HistogramChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.bars
17 |
18 | import androidx.compose.foundation.layout.size
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.unit.dp
23 | import io.androidpoet.drafter.bars.BarChart
24 | import io.androidpoet.drafter.bars.renderer.HistogramRenderer
25 |
26 | private fun getHistogramData() = listOf(1f, 2f, 2f, 3f, 3f, 3f, 4f, 4f, 5f, 5f, 5f, 5f)
27 |
28 | private fun getHistogramRenderer() =
29 | HistogramRenderer(
30 | dataPoints = getHistogramData(),
31 | binCount = 5,
32 | color = Color.Blue,
33 | )
34 |
35 | @Composable
36 | fun HistogramChartExample(
37 | modifier: Modifier = Modifier,
38 | animate: Boolean = true,
39 | ) {
40 | BarChart(
41 | renderer = getHistogramRenderer(),
42 | modifier = modifier.size(300.dp),
43 | animate = animate,
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/bars/SimpleBarChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.SimpleBarChartData
26 | import io.androidpoet.drafter.bars.renderer.BarChartRenderer
27 |
28 | private fun getBarChartData(colors: List) =
29 | SimpleBarChartData(
30 | labelsList = listOf("Jan", "Feb", "Mar", "Apr"),
31 | values = listOf(10f, 30f, 15f, 45f),
32 | colors = colors,
33 | )
34 |
35 | private fun getSimpleBarChartRenderer(colors: List) =
36 | BarChartRenderer(getBarChartData(colors = colors))
37 |
38 | @Composable
39 | fun SimpleBarChartExample(
40 | colors: List,
41 | modifier: Modifier = Modifier,
42 | ) {
43 | BarChart(
44 | renderer = getSimpleBarChartRenderer(colors = colors),
45 | modifier =
46 | modifier
47 | .height(300.dp)
48 | .fillMaxWidth(),
49 | animate = true,
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/bars/StackedBarChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.StackedBarChartData
26 | import io.androidpoet.drafter.bars.renderer.StackedBarChartRenderer
27 |
28 | private fun getStackedBarChartData(colors: List) =
29 | StackedBarChartData(
30 | labelsList = listOf("Q1", "Q2", "Q3"),
31 | stacks =
32 | listOf(
33 | listOf(10f, 15f, 5f), // Q1
34 | listOf(8f, 12f, 20f), // Q2
35 | listOf(18f, 10f, 15f), // Q3
36 | ),
37 | colors = colors,
38 | )
39 |
40 | private fun getStackedBarChartRenderer(colors: List) =
41 | StackedBarChartRenderer(getStackedBarChartData(colors = colors))
42 |
43 | @Composable
44 | fun StackedBarChartExample(
45 | colors: List,
46 | modifier: Modifier = Modifier,
47 | ) {
48 | BarChart(
49 | renderer = getStackedBarChartRenderer(colors = colors),
50 | modifier =
51 | modifier
52 | .height(300.dp)
53 | .fillMaxWidth(),
54 | animate = true,
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/bars/WaterfallChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.bars
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.bars.BarChart
25 | import io.androidpoet.drafter.bars.model.WaterfallChartData
26 | import io.androidpoet.drafter.bars.renderer.WaterfallChartRenderer
27 |
28 | private fun getWaterfallChartRenderer(colors: List) =
29 | WaterfallChartRenderer(
30 | WaterfallChartData(
31 | labelsList = listOf("Start", "Revenue", "Cost", "Profit"),
32 | values = listOf(+50f, -20f, +30f), // Changes from 'Start'
33 | colors = colors,
34 | initialValue = 100f, // Start from 100
35 | ),
36 | )
37 |
38 | @Composable
39 | fun WaterfallChartExample(
40 | colors: List,
41 | modifier: Modifier = Modifier,
42 | ) {
43 | BarChart(
44 | renderer = getWaterfallChartRenderer(colors = colors),
45 | modifier =
46 | modifier
47 | .height(300.dp)
48 | .fillMaxWidth(),
49 | animate = true,
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/buble/BubbleChart.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.buble
17 |
18 | import androidx.compose.foundation.layout.size
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.unit.dp
23 | import io.androidpoet.drafter.buble.BubbleChart
24 | import io.androidpoet.drafter.buble.BubbleChartData
25 | import io.androidpoet.drafter.buble.SimpleBubbleChartDataRenderer
26 |
27 | private fun getBubbleChartData(colors: List) =
28 | BubbleChartData(
29 | series =
30 | listOf(
31 | listOf(
32 | BubbleChartData.BubbleData(10f, 26f, 30f, colors[0]),
33 | BubbleChartData.BubbleData(26f, 30f, 60f, colors[0]),
34 | BubbleChartData.BubbleData(26f, 46f, 45f, colors[0]),
35 | ),
36 | listOf(
37 | BubbleChartData.BubbleData(14f, 15f, 30f, colors[1]),
38 | BubbleChartData.BubbleData(22f, 36f, 45f, colors[1]),
39 | BubbleChartData.BubbleData(90f, 57f, 75f, colors[1]),
40 | ),
41 | listOf(
42 | BubbleChartData.BubbleData(8f, 9f, 90f, colors[2]),
43 | BubbleChartData.BubbleData(20f, 57f, 45f, colors[2]),
44 | BubbleChartData.BubbleData(40f, 50f, 60f, colors[2]),
45 | ),
46 | listOf(
47 | BubbleChartData.BubbleData(8f, 20f, 22.5f, colors[3]),
48 | BubbleChartData.BubbleData(12f, 30f, 30f, colors[3]),
49 | BubbleChartData.BubbleData(30f, 40f, 45f, colors[3]),
50 | ),
51 | ),
52 | )
53 |
54 | private fun getBubbleChartRenderer(colors: List) =
55 | SimpleBubbleChartDataRenderer(getBubbleChartData(colors = colors))
56 |
57 | @Composable
58 | fun BubbleChartExample(
59 | colors: List,
60 | modifier: Modifier = Modifier,
61 | ) {
62 | BubbleChart(
63 | renderer = getBubbleChartRenderer(colors = colors),
64 | modifier = modifier.size(300.dp),
65 | )
66 | }
67 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/gantt/GanntChartDemo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.gantt
17 |
18 | import androidx.compose.foundation.layout.size
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.unit.dp
23 | import io.androidpoet.drafter.gant.GanttChart
24 | import io.androidpoet.drafter.gant.GanttChartData
25 | import io.androidpoet.drafter.gant.GanttChartRenderer
26 | import io.androidpoet.drafter.gant.GanttTask
27 |
28 | private fun getGanttChartRenderer(colors: List) =
29 | GanttChartRenderer(
30 | GanttChartData(
31 | taskColors = colors,
32 | tasks =
33 | listOf(
34 | GanttTask("Planning", 0f, 2f),
35 | GanttTask("Design", 2f, 2f),
36 | GanttTask("Development", 4f, 3f),
37 | GanttTask("Testing", 7f, 2f),
38 | GanttTask("Deployment", 9f, 1f),
39 | ),
40 | ),
41 | )
42 |
43 | @Composable
44 | fun GanttChartExample(
45 | colors: List,
46 | modifier: Modifier = Modifier,
47 | ) {
48 | GanttChart(
49 | renderer = getGanttChartRenderer(colors = colors),
50 | modifier = modifier.size(400.dp),
51 | )
52 | }
53 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/githubgraph/GithubGraph.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.githubgraph
17 |
18 | import androidx.compose.foundation.layout.fillMaxWidth
19 | import androidx.compose.foundation.layout.height
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.heatmap.ContributionData
25 | import io.androidpoet.drafter.heatmap.ContributionHeatmapData
26 | import io.androidpoet.drafter.heatmap.Heatmap
27 | import io.androidpoet.drafter.heatmap.HeatmapRenderer
28 | import kotlinx.datetime.Clock
29 | import kotlin.random.Random
30 | import kotlin.time.Duration.Companion.days
31 |
32 | private fun getHeatmapRenderer(color: Color) =
33 | HeatmapRenderer(
34 | ContributionHeatmapData(
35 | baseColor = color,
36 | contributions =
37 | buildList {
38 | val now = Clock.System.now()
39 | repeat(365) { day ->
40 | val date = now.minus(day.days)
41 | val count = if (Random.nextFloat() > 0.6f) Random.nextInt(1, 15) else 0
42 | add(ContributionData(date, count))
43 | }
44 | },
45 | ),
46 | )
47 |
48 | @Composable
49 | fun GithubGraph(
50 | modifier: Modifier = Modifier,
51 | color: Color,
52 | ) {
53 | Heatmap(
54 | renderer = getHeatmapRenderer(color = color),
55 | modifier =
56 | Modifier
57 | .fillMaxWidth()
58 | .height(112.dp),
59 | )
60 | }
61 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/line/GroupedLineChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.line
17 | import androidx.compose.foundation.layout.fillMaxSize
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.ui.Modifier
20 | import androidx.compose.ui.graphics.Color
21 | import io.androidpoet.drafter.lines.LineChart
22 | import io.androidpoet.drafter.lines.model.GroupedLineChartData
23 | import io.androidpoet.drafter.lines.renderer.GroupedLineChartRenderer
24 |
25 | private fun getGroupedLineChartData(colors: List) =
26 | GroupedLineChartData(
27 | labels = listOf("Q1", "Q2", "Q3", "Q4"),
28 | itemNames = listOf("Product A", "Product B"),
29 | groupedValues =
30 | listOf(
31 | listOf(10f, 15f),
32 | listOf(20f, 25f),
33 | listOf(15f, 10f),
34 | listOf(25f, 20f),
35 | ),
36 | colors = colors,
37 | )
38 |
39 | private fun getGroupedLineChartRenderer(colors: List) =
40 | GroupedLineChartRenderer(getGroupedLineChartData(colors = colors))
41 |
42 | @Composable
43 | fun GroupedLineChartExample(
44 | colors: List,
45 | modifier: Modifier = Modifier,
46 | ) {
47 | LineChart(
48 | renderer = getGroupedLineChartRenderer(colors = colors),
49 | modifier = modifier.fillMaxSize(),
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/line/ScatterPlotChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.line
17 |
18 | import androidx.compose.foundation.layout.size
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.unit.dp
23 | import io.androidpoet.drafter.scatterplot.ScatterPlot
24 | import io.androidpoet.drafter.scatterplot.SimpleScatterPlotRenderer
25 | import io.androidpoet.drafter.scatterplot.model.ScatterPlotData
26 | import kotlin.random.Random
27 |
28 | private fun getScatterPlotRenderer(colors: List) =
29 | SimpleScatterPlotRenderer(
30 | ScatterPlotData(
31 | points =
32 | List(30) {
33 | Pair(
34 | Random.nextFloat() * 50f,
35 | Random.nextFloat() * 50f,
36 | )
37 | },
38 | pointColors =
39 | List(30) {
40 | if (colors.isNotEmpty()) colors[it % colors.size] else Color.Gray
41 | },
42 | ),
43 | )
44 |
45 | @Composable
46 | fun ScatterPlotChartExample(
47 | colors: List,
48 | modifier: Modifier = Modifier,
49 | ) {
50 | ScatterPlot(
51 | modifier = Modifier.size(300.dp),
52 | renderer = getScatterPlotRenderer(colors = colors),
53 | )
54 | }
55 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/line/SimpleLineChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.line
17 | import androidx.compose.foundation.layout.fillMaxSize
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.ui.Modifier
20 | import androidx.compose.ui.graphics.Color
21 | import io.androidpoet.drafter.lines.LineChart
22 | import io.androidpoet.drafter.lines.model.SimpleLineChartData
23 | import io.androidpoet.drafter.lines.renderer.LineChartRenderer
24 |
25 | private fun getLineChartRenderer(colors: List) =
26 | LineChartRenderer(
27 | SimpleLineChartData(
28 | labels = listOf("A", "B", "C", "D"),
29 | values = listOf(10f, 20f, 15f, 25f),
30 | color = colors.first(),
31 | ),
32 | )
33 |
34 | @Composable
35 | fun SimpleLineChartExample(
36 | colors: List,
37 | modifier: Modifier = Modifier,
38 | ) {
39 | LineChart(
40 | renderer = getLineChartRenderer(colors = colors),
41 | modifier = modifier.fillMaxSize(),
42 | )
43 | }
44 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/line/StackedLineChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.line
17 |
18 | import androidx.compose.foundation.layout.fillMaxSize
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.graphics.Color
22 | import io.androidpoet.drafter.lines.LineChart
23 | import io.androidpoet.drafter.lines.model.StackedLineChartData
24 | import io.androidpoet.drafter.lines.renderer.StackedLineChartRenderer
25 |
26 | private fun getStackedLineChartRenderer(colors: List) =
27 | StackedLineChartRenderer(
28 | StackedLineChartData(
29 | labels = listOf("Jan", "Feb", "Mar", "Apr"),
30 | stacks =
31 | listOf(
32 | listOf(5f, 5f, 2f),
33 | listOf(7f, 3f, 4f),
34 | listOf(6f, 4f, 3f),
35 | listOf(8f, 2f, 5f),
36 | ),
37 | colors = colors,
38 | ),
39 | )
40 |
41 | @Composable
42 | fun StackedLineChartExample(
43 | colors: List,
44 | modifier: Modifier = Modifier,
45 | ) {
46 | LineChart(
47 | renderer = getStackedLineChartRenderer(colors = colors),
48 | modifier = Modifier.fillMaxSize(),
49 | )
50 | }
51 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/manager/ChartThemeManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.manager
17 |
18 | import androidx.compose.runtime.State
19 | import androidx.compose.runtime.mutableStateOf
20 | import androidx.compose.ui.graphics.Color
21 |
22 | object ChartThemeManager {
23 | enum class ColorTheme {
24 | MATERIAL,
25 | MODERN,
26 | NATURE,
27 | PROFESSIONAL,
28 | }
29 |
30 | private val palettes =
31 | mapOf(
32 | ColorTheme.MATERIAL to
33 | listOf(
34 | Color(0xFF2196F3), // Primary Blue
35 | Color(0xFFFF9800), // Orange
36 | Color(0xFF4CAF50), // Green
37 | Color(0xFFF44336), // Red
38 | Color(0xFF9C27B0), // Purple
39 | Color(0xFF795548), // Brown
40 | Color(0xFF009688), // Teal
41 | Color(0xFFE91E63), // Pink
42 | ),
43 | ColorTheme.MODERN to
44 | listOf(
45 | Color(0xFF7E57C2), // Purple
46 | Color(0xFF26A69A), // Teal
47 | Color(0xFFFF7043), // Coral
48 | Color(0xFF66BB6A), // Light Green
49 | Color(0xFF5C6BC0), // Indigo
50 | Color(0xFFFFCA28), // Amber
51 | Color(0xFF42A5F5), // Light Blue
52 | Color(0xFFEC407A), // Pink
53 | ),
54 | ColorTheme.NATURE to
55 | listOf(
56 | Color(0xFF66BB6A), // Green
57 | Color(0xFF42A5F5), // Sky Blue
58 | Color(0xFFFFB74D), // Light Orange
59 | Color(0xFF8D6E63), // Brown
60 | Color(0xFF26A69A), // Sea Green
61 | Color(0xFFFFCC80), // Pale Orange
62 | Color(0xFF81C784), // Light Green
63 | Color(0xFF7986CB), // Blue Grey
64 | ),
65 | ColorTheme.PROFESSIONAL to
66 | listOf(
67 | Color(0xFF5C6BC0), // Indigo
68 | Color(0xFF8D6E63), // Brown
69 | Color(0xFF26A69A), // Teal
70 | Color(0xFF78909C), // Blue Grey
71 | Color(0xFF7E57C2), // Deep Purple
72 | Color(0xFF66BB6A), // Green
73 | Color(0xFF29B6F6), // Light Blue
74 | Color(0xFFBDBDBD), // Grey
75 | ),
76 | )
77 |
78 | private val githubColors =
79 | listOf(
80 | Color(0xFF0E4429), // Darkest
81 | Color(0xFF006D32), // Dark
82 | Color(0xFF26A641), // Medium
83 | Color(0xFF39D353), // Light
84 | )
85 |
86 | private fun getFullPalette(theme: ColorTheme): List =
87 | palettes[theme] ?: palettes[ColorTheme.MATERIAL]!!
88 |
89 | private val _currentTheme = mutableStateOf(ColorTheme.MATERIAL)
90 | private val _currentFullPalette = mutableStateOf(getFullPalette(ColorTheme.MATERIAL))
91 | val currentTheme: State = _currentTheme
92 | val palette: State> = _currentFullPalette
93 |
94 | fun setTheme(theme: ColorTheme) {
95 | _currentTheme.value = theme
96 | _currentFullPalette.value = getFullPalette(theme)
97 | }
98 |
99 | fun getGithubColors() = githubColors
100 | }
101 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/pie/PieChartExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.pie
17 |
18 | import androidx.compose.foundation.layout.size
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.unit.dp
23 | import io.androidpoet.drafter.pie.PieChart
24 | import io.androidpoet.drafter.pie.model.PieChartData
25 | import io.androidpoet.drafter.pie.renderer.DonutChartRenderer
26 | import io.androidpoet.drafter.pie.renderer.PieChartRenderer
27 |
28 | private fun getPieChartRenderer(colors: List) =
29 | PieChartRenderer(
30 | PieChartData(
31 | slices =
32 | listOf(
33 | PieChartData.Slice(value = 40f, color = colors[0], label = "Red"),
34 | PieChartData.Slice(value = 30f, color = colors[1], label = "Green"),
35 | PieChartData.Slice(value = 20f, color = colors[2], label = "Blue"),
36 | PieChartData.Slice(value = 10f, color = colors[3], label = "Purple"),
37 | ),
38 | ),
39 | )
40 |
41 | private fun getDonutPieChartRenderer(colors: List) =
42 | DonutChartRenderer(
43 | PieChartData(
44 | slices =
45 | listOf(
46 | PieChartData.Slice(value = 40f, color = colors[0], label = "Red"),
47 | PieChartData.Slice(value = 30f, color = colors[1], label = "Green"),
48 | PieChartData.Slice(value = 20f, color = colors[2], label = "Blue"),
49 | PieChartData.Slice(value = 10f, color = colors[3], label = "Purple"),
50 | ),
51 | ),
52 | )
53 |
54 | @Composable
55 | fun PieChartExample(
56 | colors: List,
57 | modifier: Modifier = Modifier,
58 | ) {
59 | PieChart(
60 | renderer = getPieChartRenderer(colors = colors),
61 | modifier = Modifier.size(300.dp),
62 | animate = true,
63 | )
64 | }
65 |
66 | @Composable
67 | fun DonutChartExample(
68 | colors: List,
69 | modifier: Modifier = Modifier,
70 | ) {
71 | PieChart(
72 | renderer = getDonutPieChartRenderer(colors = colors),
73 | modifier = Modifier.size(200.dp),
74 | animate = true,
75 | )
76 | }
77 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/radar/RadarChart.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.radar
17 |
18 | import androidx.compose.foundation.isSystemInDarkTheme
19 | import androidx.compose.foundation.layout.size
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.unit.dp
24 | import io.androidpoet.drafter.radar.RadarChart
25 | import io.androidpoet.drafter.radar.model.RadarChartData
26 | import io.androidpoet.drafter.radar.renderer.RadarChartRenderer
27 |
28 | private fun getRadarRenderer(colors: List) =
29 | RadarChartRenderer(
30 | data =
31 | listOf(
32 | RadarChartData(
33 | mapOf(
34 | "Execution" to 0.8f,
35 | "Landing" to 0.6f,
36 | "Difficulty" to 0.9f,
37 | "Style" to 0.7f,
38 | "Creativity" to 0.85f,
39 | ),
40 | ),
41 | ),
42 | colors = colors,
43 | )
44 |
45 | @Composable
46 | fun RadarChartExample(
47 | colors: List,
48 | modifier: Modifier = Modifier,
49 | ) {
50 | RadarChart(
51 | modifier = modifier.size(300.dp),
52 | renderer = getRadarRenderer(colors),
53 | isSystemInDarkTheme = isSystemInDarkTheme(),
54 | )
55 | }
56 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.ui.theme
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | val Purple80 = Color(0xFFD0BCFF)
21 | val PurpleGrey80 = Color(0xFFCCC2DC)
22 | val Pink80 = Color(0xFFEFB8C8)
23 |
24 | val Purple40 = Color(0xFF6650a4)
25 | val PurpleGrey40 = Color(0xFF625b71)
26 | val Pink40 = Color(0xFF7D5260)
27 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.ui.theme
17 |
18 | import android.app.Activity
19 | import android.os.Build
20 | import androidx.compose.foundation.isSystemInDarkTheme
21 | import androidx.compose.material3.MaterialTheme
22 | import androidx.compose.material3.darkColorScheme
23 | import androidx.compose.material3.dynamicDarkColorScheme
24 | import androidx.compose.material3.dynamicLightColorScheme
25 | import androidx.compose.material3.lightColorScheme
26 | import androidx.compose.runtime.Composable
27 | import androidx.compose.runtime.SideEffect
28 | import androidx.compose.ui.graphics.toArgb
29 | import androidx.compose.ui.platform.LocalContext
30 | import androidx.compose.ui.platform.LocalView
31 | import androidx.core.view.WindowCompat
32 |
33 | private val DarkColorScheme =
34 | darkColorScheme(
35 | primary = Purple80,
36 | secondary = PurpleGrey80,
37 | tertiary = Pink80,
38 | )
39 |
40 | private val LightColorScheme =
41 | lightColorScheme(
42 | primary = Purple40,
43 | secondary = PurpleGrey40,
44 | tertiary = Pink40,
45 | /* Other default colors to override
46 | background = Color(0xFFFFFBFE),
47 | surface = Color(0xFFFFFBFE),
48 | onPrimary = Color.White,
49 | onSecondary = Color.White,
50 | onTertiary = Color.White,
51 | onBackground = Color(0xFF1C1B1F),
52 | onSurface = Color(0xFF1C1B1F),
53 | */
54 | )
55 |
56 | @Composable
57 | fun DrafterDemoTheme(
58 | darkTheme: Boolean = isSystemInDarkTheme(),
59 | dynamicColor: Boolean = true,
60 | content: @Composable () -> Unit,
61 | ) {
62 | val colorScheme =
63 | when {
64 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
65 | val context = LocalContext.current
66 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
67 | }
68 |
69 | darkTheme -> DarkColorScheme
70 | else -> LightColorScheme
71 | }
72 | val view = LocalView.current
73 | if (!view.isInEditMode) {
74 | SideEffect {
75 | val window = (view.context as Activity).window
76 | window.statusBarColor = colorScheme.primary.toArgb()
77 | WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
78 | }
79 | }
80 |
81 | MaterialTheme(
82 | colorScheme = colorScheme,
83 | typography = Typography,
84 | content = content,
85 | )
86 | }
87 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/kotlin/io/androidpoet/drafter/baselineprofile/app/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile.app.ui.theme
17 |
18 | import androidx.compose.material3.Typography
19 | import androidx.compose.ui.text.TextStyle
20 | import androidx.compose.ui.text.font.FontFamily
21 | import androidx.compose.ui.text.font.FontWeight
22 | import androidx.compose.ui.unit.sp
23 |
24 | val Typography =
25 | Typography(
26 | bodyLarge =
27 | TextStyle(
28 | fontFamily = FontFamily.Default,
29 | fontWeight = FontWeight.Normal,
30 | fontSize = 16.sp,
31 | lineHeight = 24.sp,
32 | letterSpacing = 0.5.sp,
33 | ),
34 | /* Other default text styles to override
35 | titleLarge = TextStyle(
36 | fontFamily = FontFamily.Default,
37 | fontWeight = FontWeight.Normal,
38 | fontSize = 22.sp,
39 | lineHeight = 28.sp,
40 | letterSpacing = 0.sp
41 | ),
42 | labelSmall = TextStyle(
43 | fontFamily = FontFamily.Default,
44 | fontWeight = FontWeight.Medium,
45 | fontSize = 11.sp,
46 | lineHeight = 16.sp,
47 | letterSpacing = 0.5.sp
48 | )
49 | */
50 | )
51 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
23 |
24 |
25 |
31 |
34 |
37 |
38 |
39 |
40 |
46 |
47 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/baselineprofile-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #FFBB86FC
19 | #FF6200EE
20 | #FF3700B3
21 | #FF03DAC5
22 | #FF018786
23 | #FF000000
24 | #FFFFFFFF
25 |
26 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | benchmark-app
19 |
20 |
--------------------------------------------------------------------------------
/baselineprofile-app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
22 |
23 |
--------------------------------------------------------------------------------
/baselineprofile/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/baselineprofile/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import io.androidpoet.drafter.Configuration
2 |
3 | @Suppress("DSL_SCOPE_VIOLATION")
4 | plugins {
5 | id(
6 | libs.plugins.android.test
7 | .get()
8 | .pluginId,
9 | )
10 | id(
11 | libs.plugins.kotlin.android
12 | .get()
13 | .pluginId,
14 | )
15 | id(
16 | libs.plugins.baseline.profile
17 | .get()
18 | .pluginId,
19 | )
20 | }
21 |
22 | android {
23 | namespace = "io.androidpoet.drafter.baselineprofile"
24 | compileSdk = Configuration.compileSdk
25 |
26 | compileOptions {
27 | sourceCompatibility = JavaVersion.VERSION_11
28 | targetCompatibility = JavaVersion.VERSION_11
29 | }
30 |
31 | kotlinOptions {
32 | jvmTarget = libs.versions.jvmTarget.get()
33 | }
34 |
35 | defaultConfig {
36 | minSdk = 24
37 | targetSdk = Configuration.targetSdk
38 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
39 | }
40 |
41 | targetProjectPath = ":baselineprofile-app"
42 |
43 | testOptions.managedDevices.devices {
44 | maybeCreate("pixel6api31").apply {
45 | device = "Pixel 6"
46 | apiLevel = 31
47 | systemImageSource = "aosp"
48 | }
49 | }
50 | }
51 | baselineProfile {
52 | managedDevices += "pixel6api31"
53 | useConnectedDevices = true
54 | }
55 |
56 | dependencies {
57 | implementation(libs.androidx.test.runner)
58 | implementation(libs.androidx.test.uiautomator)
59 | implementation(libs.androidx.benchmark.macro)
60 | implementation(libs.androidx.profileinstaller)
61 | }
62 |
--------------------------------------------------------------------------------
/baselineprofile/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
--------------------------------------------------------------------------------
/baselineprofile/src/main/kotlin/io/androidpoet/drafter/baselineprofile/BaselineProfileGenerator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.baselineprofile
17 |
18 | import android.os.Build
19 | import androidx.annotation.RequiresApi
20 | import androidx.benchmark.macro.junit4.BaselineProfileRule
21 | import org.junit.Rule
22 | import org.junit.Test
23 |
24 | @RequiresApi(Build.VERSION_CODES.P)
25 | class BaselineProfileGenerator {
26 | @get:Rule
27 | val baselineProfileRule = BaselineProfileRule()
28 |
29 | @Test
30 | fun startup() =
31 | baselineProfileRule.collect(
32 | packageName = "io.androidpoet.drafter.baselineprofile.app",
33 | stableIterations = 2,
34 | maxIterations = 8,
35 | ) {
36 | pressHome()
37 | startActivityAndWait()
38 | device.waitForIdle()
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | @Suppress("DSL_SCOPE_VIOLATION")
3 | plugins {
4 | alias(libs.plugins.android.application) apply false
5 | alias(libs.plugins.android.library) apply false
6 | alias(libs.plugins.kotlin.multiplatform) apply false
7 | alias(libs.plugins.compose.compiler) apply false
8 | alias(libs.plugins.kotlin.android) apply false
9 | alias(libs.plugins.jetbrains.compose) apply false
10 | alias(libs.plugins.baseline.profile) apply false
11 | alias(libs.plugins.kotlin.binary.compatibility)
12 | alias(libs.plugins.nexus.plugin)
13 | alias(libs.plugins.spotless)
14 | alias(libs.plugins.dokka)
15 | }
16 |
17 | subprojects {
18 | apply(
19 | plugin =
20 | rootProject.libs.plugins.spotless
21 | .get()
22 | .pluginId,
23 | )
24 |
25 | configure {
26 | kotlin {
27 | target("**/*.kt")
28 | targetExclude("$buildDir/**/*.kt")
29 | ktlint().editorConfigOverride(
30 | mapOf(
31 | "indent_size" to "2",
32 | "continuation_indent_size" to "2",
33 | ),
34 | )
35 | licenseHeaderFile(rootProject.file("spotless/copyright.kt"))
36 | trimTrailingWhitespace()
37 | endWithNewline()
38 | }
39 | format("xml") {
40 | target("**/*.xml")
41 | targetExclude("**/build/**/*.xml")
42 | licenseHeaderFile(rootProject.file("spotless/copyright.xml"), "(<[^!?])")
43 | trimTrailingWhitespace()
44 | endWithNewline()
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | `kotlin-dsl`
3 | }
4 |
5 | repositories {
6 | mavenCentral()
7 | }
8 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/io/androidpoet/drafter/Configuration.kt:
--------------------------------------------------------------------------------
1 | package io.androidpoet.drafter
2 |
3 | object Configuration {
4 | const val compileSdk = 34
5 | const val targetSdk = 33
6 | const val minSdk = 21
7 | const val majorVersion = 0
8 | const val minorVersion = 1
9 | const val patchVersion = 8
10 | const val versionName = "$majorVersion.$minorVersion.$patchVersion"
11 | const val versionCode = 1
12 | const val snapshotVersionName = "$majorVersion.$minorVersion.${patchVersion + 1}-SNAPSHOT"
13 | const val artifactGroup = "io.github.androidpoet"
14 | }
15 |
--------------------------------------------------------------------------------
/chartsx.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/chartsx.mp4
--------------------------------------------------------------------------------
/drafter/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/drafter/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import io.androidpoet.drafter.Configuration
2 | import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
3 |
4 | @Suppress("DSL_SCOPE_VIOLATION")
5 | plugins {
6 | alias(libs.plugins.android.library)
7 | alias(libs.plugins.kotlin.multiplatform)
8 | alias(libs.plugins.jetbrains.compose)
9 | alias(libs.plugins.compose.compiler)
10 | alias(libs.plugins.nexus.plugin)
11 | alias(libs.plugins.baseline.profile)
12 | }
13 |
14 | apply(from = "$rootDir/scripts/publish-module.gradle.kts")
15 |
16 | mavenPublishing {
17 | val artifactId = "drafter"
18 | coordinates(
19 | Configuration.artifactGroup,
20 | artifactId,
21 | rootProject.extra.get("libVersion").toString(),
22 | )
23 |
24 | pom {
25 | name.set(artifactId)
26 | description.set(
27 | "\uD83D\uDCCA A powerful, flexible charting library for Compose Multiplatform applications",
28 | )
29 | }
30 | }
31 |
32 | kotlin {
33 | androidTarget { publishLibraryVariants("release") }
34 | jvm("desktop")
35 | iosX64()
36 | iosArm64()
37 | iosSimulatorArm64()
38 | macosX64()
39 | macosArm64()
40 | js(IR) {
41 | browser()
42 | nodejs()
43 | }
44 | @OptIn(ExperimentalWasmDsl::class)
45 | wasmJs {
46 | browser()
47 | nodejs()
48 | binaries.executable()
49 | }
50 | @Suppress("OPT_IN_USAGE")
51 | applyHierarchyTemplate {
52 | common {
53 | group("jvm") {
54 | withAndroidTarget()
55 | withJvm()
56 | }
57 | group("skia") {
58 | withJvm()
59 | group("darwin") {
60 | group("apple") {
61 | group("ios") {
62 | withIosX64()
63 | withIosArm64()
64 | withIosSimulatorArm64()
65 | }
66 | group("macos") {
67 | withMacosX64()
68 | withMacosArm64()
69 | }
70 | }
71 | withJs()
72 | withWasmJs()
73 | }
74 | }
75 | }
76 | }
77 |
78 | targets.configureEach {
79 | compilations.configureEach {
80 | compilerOptions.configure {
81 | freeCompilerArgs.add("-Xexpect-actual-classes")
82 | }
83 | }
84 | }
85 |
86 | sourceSets {
87 | val commonMain by getting {
88 | dependencies {
89 | implementation(compose.ui)
90 | implementation(compose.material3)
91 | implementation(compose.runtime)
92 | implementation(compose.animation)
93 | implementation(libs.kotlinx.datetime)
94 | }
95 | }
96 | }
97 |
98 | explicitApi()
99 | }
100 | composeCompiler {
101 | enableStrongSkippingMode = true
102 | }
103 | android {
104 | compileSdk = Configuration.compileSdk
105 | namespace = "io.androidpoet.drafter"
106 | defaultConfig {
107 | minSdk = Configuration.minSdk
108 | }
109 |
110 | buildFeatures {
111 | compose = true
112 | buildConfig = false
113 | }
114 |
115 | compileOptions {
116 | sourceCompatibility = JavaVersion.VERSION_1_8
117 | targetCompatibility = JavaVersion.VERSION_1_8
118 | }
119 |
120 | packaging {
121 | resources {
122 | excludes.add("/META-INF/{AL2.0,LGPL2.1}")
123 | }
124 | }
125 |
126 | lint {
127 | abortOnError = false
128 | }
129 | }
130 |
131 | baselineProfile {
132 | baselineProfileOutputDir = "../../src/androidMain"
133 | filter {
134 | include("io.androidpoet.drafter.**")
135 | }
136 | }
137 |
138 | dependencies {
139 | baselineProfile(project(":baselineprofile"))
140 | }
141 |
142 | tasks.withType {
143 | kotlinOptions {
144 | jvmTarget = "1.8"
145 | freeCompilerArgs +=
146 | listOf(
147 | "-Xexplicit-api=strict",
148 | "-Xopt-in=androidx.compose.material3.ExperimentalMaterial3Api",
149 | )
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/bars/BarChartDataRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.bars
17 |
18 | import androidx.compose.ui.graphics.drawscope.DrawScope
19 |
20 | public interface BarChartDataRenderer {
21 | /** The labels for the X-axis (one per bar group, bin, etc.). */
22 | public fun getLabels(): List
23 |
24 | /** How many bars are in each group? (e.g. 1 for simple/histogram, >1 for grouped) */
25 | public fun barsPerGroup(): Int
26 |
27 | /** The maximum Y value to use for scaling the bars. */
28 | public fun calculateMaxValue(): Float
29 |
30 | /**
31 | * Given [chartWidth], [dataSize], and [barsPerGroup], return (barWidth, groupSpacing).
32 | * Must clamp or safeguard so values never go negative.
33 | */
34 | public fun calculateBarAndSpacing(
35 | chartWidth: Float,
36 | dataSize: Int,
37 | barsPerGroup: Int,
38 | ): Pair
39 |
40 | /**
41 | * For layout, how wide is a single "group" on the X-axis? (barWidth * barsPerGroup + internal spacing).
42 | */
43 | public fun calculateGroupWidth(
44 | barWidth: Float,
45 | barsPerGroup: Int,
46 | ): Float
47 |
48 | /**
49 | * Draw the bars for group [index]. This is where grouped, stacked, or histogram logic goes.
50 | */
51 | public fun drawBars(
52 | drawScope: DrawScope,
53 | index: Int,
54 | left: Float,
55 | barWidth: Float,
56 | groupSpacing: Float,
57 | chartBottom: Float,
58 | chartHeight: Float,
59 | maxValue: Float,
60 | animationProgress: Float,
61 | )
62 | }
63 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/bars/model/BarChartModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.bars.model
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | /**
21 | * Data class representing data for a grouped bar chart where multiple bars are shown side by side
22 | * for each category/label.
23 | *
24 | * @property labelsList List of labels for each group on the X-axis
25 | * @property itemNames Names of individual items within each group (e.g., "Men", "Women" or "Q1", "Q2", "Q3")
26 | * @property groupedValues List of lists containing values for each item in each group
27 | * @property colors List of colors to be used for different items in the groups
28 | */
29 | public data class GroupedBarChartData(
30 | val labelsList: List,
31 | val itemNames: List,
32 | val groupedValues: List>,
33 | val colors: List,
34 | )
35 |
36 | /**
37 | * Data class representing data for a simple bar chart with single bars.
38 | *
39 | * @property labelsList List of labels for the X-axis
40 | * @property values List of values for each bar
41 | * @property colors List of colors for each bar
42 | */
43 | public data class SimpleBarChartData(
44 | val labelsList: List,
45 | val values: List,
46 | val colors: List,
47 | )
48 |
49 | /**
50 | * Data class representing data for a stacked bar chart where bars are stacked on top of each other.
51 | *
52 | * @property labelsList List of labels for the X-axis
53 | * @property stacks List of lists containing values for each stack segment
54 | * @property colors List of colors for each stack segment
55 | */
56 | public data class StackedBarChartData(
57 | val labelsList: List,
58 | val stacks: List>,
59 | val colors: List,
60 | )
61 |
62 | /**
63 | * Data class representing data for a waterfall chart that shows running total.
64 | *
65 | * @property labelsList List of labels for the X-axis
66 | * @property values List of values representing changes at each step
67 | * @property colors List of colors for each bar
68 | * @property initialValue Starting value for the waterfall chart (defaults to 0)
69 | */
70 | public data class WaterfallChartData(
71 | val labelsList: List,
72 | val values: List,
73 | val colors: List,
74 | val initialValue: Float = 0f,
75 | )
76 |
77 | /**
78 | * Data class representing histogram data with binned values.
79 | *
80 | * @property labels List of bin labels for the X-axis
81 | * @property frequencies List of frequencies/counts for each bin
82 | * @property colors List of colors for each bin
83 | */
84 | public data class HistogramData(
85 | val labels: List,
86 | val frequencies: List,
87 | val colors: List,
88 | )
89 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/bars/renderer/BarChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.bars.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.geometry.Size
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import io.androidpoet.drafter.bars.BarChartDataRenderer
23 | import io.androidpoet.drafter.bars.model.SimpleBarChartData
24 |
25 | /**
26 | * A renderer for simple bar charts where each category has a single bar.
27 | * This is the most basic form of a bar chart with one value per label.
28 | *
29 | * @property data The [SimpleBarChartData] containing labels, values, and colors for the bars
30 | */
31 | public class BarChartRenderer(
32 | public val data: SimpleBarChartData,
33 | ) : BarChartDataRenderer {
34 | /**
35 | * Returns the list of labels for the X-axis.
36 | */
37 | override fun getLabels(): List = data.labelsList
38 |
39 | /**
40 | * Returns 1 since simple bar charts have one bar per group.
41 | */
42 | override fun barsPerGroup(): Int = 1
43 |
44 | /**
45 | * Calculates the maximum value across all bars for scaling purposes.
46 | * Returns 0 if there are no values.
47 | */
48 | override fun calculateMaxValue(): Float = data.values.maxOrNull() ?: 0f
49 |
50 | /**
51 | * Calculates the width of bars and spacing between them based on chart dimensions.
52 | *
53 | * @param chartWidth Total width of the chart area
54 | * @param dataSize Number of data points (bars) to display
55 | * @param barsPerGroup Always 1 for simple bar charts (unused parameter)
56 | * @return Pair of (barWidth, spacing)
57 | */
58 | override fun calculateBarAndSpacing(
59 | chartWidth: Float,
60 | dataSize: Int,
61 | barsPerGroup: Int,
62 | ): Pair {
63 | val totalSpacing = chartWidth * 0.1f
64 | val groupSpacing = totalSpacing / (dataSize + 1)
65 | val availableWidth = chartWidth - totalSpacing
66 | val barWidth = availableWidth / dataSize
67 |
68 | return Pair(barWidth, groupSpacing)
69 | }
70 |
71 | /**
72 | * Returns the width of a single bar as the group width.
73 | * For simple bar charts, group width equals bar width.
74 | */
75 | override fun calculateGroupWidth(
76 | barWidth: Float,
77 | barsPerGroup: Int,
78 | ): Float = barWidth
79 |
80 | /**
81 | * Draws a single bar at the specified position.
82 | *
83 | * @param drawScope Drawing context
84 | * @param index Index of the current bar
85 | * @param left Left position of the bar
86 | * @param barWidth Width of the bar
87 | * @param groupSpacing Spacing between bars (unused in simple charts)
88 | * @param chartBottom Y-coordinate of chart bottom
89 | * @param chartHeight Total height of chart
90 | * @param maxValue Maximum value for scaling
91 | * @param animationProgress Current animation progress (0-1)
92 | */
93 | override fun drawBars(
94 | drawScope: DrawScope,
95 | index: Int,
96 | left: Float,
97 | barWidth: Float,
98 | groupSpacing: Float,
99 | chartBottom: Float,
100 | chartHeight: Float,
101 | maxValue: Float,
102 | animationProgress: Float,
103 | ) {
104 | val value = data.values[index]
105 | val barHeight = (value / maxValue) * chartHeight * animationProgress
106 | val color = data.colors.getOrElse(index) { Color.Gray }
107 | drawScope.drawRect(
108 | color = color,
109 | topLeft = Offset(left, chartBottom - barHeight),
110 | size = Size(barWidth, barHeight),
111 | )
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/bars/renderer/StackedBarChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.bars.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.geometry.Size
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import io.androidpoet.drafter.bars.BarChartDataRenderer
23 | import io.androidpoet.drafter.bars.model.StackedBarChartData
24 | import kotlin.math.roundToInt
25 |
26 | /**
27 | * A renderer for stacked bar charts where multiple values are stacked vertically in a single bar.
28 | * The bars are distributed evenly across the available width to ensure full X-axis coverage.
29 | *
30 | * @property data The [StackedBarChartData] containing labels, stacked values, and colors for the segments
31 | */
32 | public class StackedBarChartRenderer(
33 | public val data: StackedBarChartData,
34 | ) : BarChartDataRenderer {
35 | override fun getLabels(): List =
36 | data.labelsList.map { label ->
37 | label.toFloatOrNull()?.let { formatToOneDecimal(it) } ?: label
38 | }
39 |
40 | override fun barsPerGroup(): Int = 1
41 |
42 | override fun calculateMaxValue(): Float = data.stacks.maxOf { it.sum() }
43 |
44 | /**
45 | * Calculates the width of bars and spacing between them to fill the entire chart width.
46 | * Ensures consistent spacing and bar widths across the full X-axis.
47 | *
48 | * @param chartWidth Total width of the chart area
49 | * @param dataSize Number of stacked bars to display
50 | * @param barsPerGroup Always 1 for stacked charts (unused parameter)
51 | * @return Pair of (barWidth, spacing)
52 | */
53 | override fun calculateBarAndSpacing(
54 | chartWidth: Float,
55 | dataSize: Int,
56 | barsPerGroup: Int,
57 | ): Pair {
58 | if (dataSize <= 0) return Pair(0f, 0f)
59 | val totalGapSpace = chartWidth * 0.2f // Increased from 0.1f to give more spacing
60 | val groupSpacing = totalGapSpace / (dataSize + 1)
61 | val availableWidth = chartWidth - totalGapSpace
62 | val barWidth = (availableWidth / dataSize).coerceAtLeast(0f)
63 |
64 | return Pair(barWidth, groupSpacing)
65 | }
66 |
67 | override fun calculateGroupWidth(
68 | barWidth: Float,
69 | barsPerGroup: Int,
70 | ): Float = barWidth
71 |
72 | /**
73 | * Draws a stacked bar with multiple segments, ensuring proper vertical stacking
74 | * and consistent width across the chart.
75 | */
76 | override fun drawBars(
77 | drawScope: DrawScope,
78 | index: Int,
79 | left: Float,
80 | barWidth: Float,
81 | groupSpacing: Float,
82 | chartBottom: Float,
83 | chartHeight: Float,
84 | maxValue: Float,
85 | animationProgress: Float,
86 | ) {
87 | if (index >= data.stacks.size) return
88 | var currentBottom = chartBottom
89 | val stackValues = data.stacks[index]
90 | stackValues.forEachIndexed { stackIndex, value ->
91 | val safeMaxValue = maxValue.coerceAtLeast(1e-6f) // Prevent division by zero
92 | val barHeight = (value / safeMaxValue) * chartHeight * animationProgress
93 | val barColor = data.colors.getOrElse(stackIndex) { Color.Gray }
94 | drawScope.drawRect(
95 | color = barColor,
96 | topLeft = Offset(left, currentBottom - barHeight),
97 | size = Size(barWidth, barHeight),
98 | )
99 | currentBottom -= barHeight
100 | }
101 | }
102 | }
103 |
104 | /**
105 | * Formats a float value to exactly one decimal place using platform-independent approach.
106 | *
107 | * @param value Float value to format
108 | * @return String representation with exactly one decimal place
109 | */
110 | private fun formatToOneDecimal(value: Float): String = ((value * 10).roundToInt() / 10f).toString()
111 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/buble/BarChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.buble
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.graphics.drawscope.DrawScope
20 |
21 | public class SimpleBubbleChartDataRenderer(
22 | private val data: BubbleChartData,
23 | ) : BubbleChartDataRenderer {
24 | override fun getLabels(): List = emptyList()
25 |
26 | override fun getValueRanges(): ValueRanges {
27 | val allBubbles = data.series.flatten()
28 | val xMin = 0f // Always start from 0
29 | val yMin = 0f // Always start from 0
30 | val xMax = roundToNiceNumber(allBubbles.maxOfOrNull { it.x } ?: 0f)
31 | val yMax = roundToNiceNumber(allBubbles.maxOfOrNull { it.y } ?: 0f)
32 | return ValueRanges(xMin, xMax, yMin, yMax)
33 | }
34 |
35 | override fun getMaxValues(): Pair {
36 | val ranges = getValueRanges()
37 | return Pair(ranges.xMax, ranges.yMax)
38 | }
39 |
40 | private fun roundToNiceNumber(value: Float): Float =
41 | when {
42 | value <= 50f -> (((value + 9) / 10).toInt() * 10).toFloat()
43 | value <= 100f -> (((value + 24) / 25).toInt() * 25).toFloat()
44 | else -> (((value + 49) / 50).toInt() * 50).toFloat()
45 | }
46 |
47 | override fun drawBubbles(
48 | drawScope: DrawScope,
49 | chartWidth: Float,
50 | chartHeight: Float,
51 | originX: Float,
52 | originY: Float,
53 | animationProgress: Float,
54 | ) {
55 | val ranges = getValueRanges()
56 | val maxBubbleSize = data.series.flatten().maxOfOrNull { it.size } ?: 0f
57 |
58 | data.series.forEachIndexed { seriesIndex, series ->
59 | series.forEachIndexed { bubbleIndex, bubble ->
60 | val delay = (seriesIndex * series.size + bubbleIndex) * 0.1f
61 | val bubbleProgress = (animationProgress - delay).coerceIn(0f, 1f)
62 | val x = originX + (bubble.x / ranges.xMax) * chartWidth
63 | val y = originY - (bubble.y / ranges.yMax) * chartHeight
64 | val scaleFactor = minOf(chartWidth, chartHeight) / 6f
65 | val scaledSize = (bubble.size / maxBubbleSize) * scaleFactor
66 |
67 | drawScope.drawCircle(
68 | color = bubble.color,
69 | radius = scaledSize * bubbleProgress,
70 | center = Offset(x, y),
71 | )
72 | }
73 | }
74 | }
75 | }
76 |
77 | public data class ValueRanges(
78 | val xMin: Float,
79 | val xMax: Float,
80 | val yMin: Float,
81 | val yMax: Float,
82 | )
83 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/buble/BubbleChartData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.buble
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | public data class BubbleChartData(
21 | val series: List>,
22 | ) {
23 | public data class BubbleData(
24 | val x: Float,
25 | val y: Float,
26 | val size: Float,
27 | val color: Color,
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/buble/BubbleChartDataRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.buble
17 |
18 | import androidx.compose.ui.graphics.drawscope.DrawScope
19 |
20 | public interface BubbleChartDataRenderer {
21 | public fun getLabels(): List
22 |
23 | public fun getMaxValues(): Pair // x, y
24 |
25 | public fun getValueRanges(): ValueRanges
26 |
27 | public fun drawBubbles(
28 | drawScope: DrawScope,
29 | chartWidth: Float,
30 | chartHeight: Float,
31 | originX: Float,
32 | originY: Float,
33 | animationProgress: Float,
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/gant/GantChartData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.gant
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | public data class GanttTask(
21 | val name: String,
22 | val startMonth: Float,
23 | val duration: Float,
24 | )
25 |
26 | public data class GanttChartData(
27 | val tasks: List,
28 | val taskColors: List = List(tasks.size) { Color.Blue },
29 | )
30 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/gant/GanttChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.gant
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.geometry.Size
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import kotlin.math.max
23 |
24 | public class GanttChartRenderer(
25 | public val data: GanttChartData,
26 | ) {
27 | public fun calculateMaxValues(): Pair {
28 | val maxMonth = data.tasks.maxOfOrNull { it.startMonth + it.duration } ?: 1f
29 | return Pair(max(maxMonth, 1f), max(data.tasks.size.toFloat(), 1f))
30 | }
31 |
32 | public fun drawTasks(
33 | drawScope: DrawScope,
34 | chartLeft: Float,
35 | chartTop: Float,
36 | chartWidth: Float,
37 | chartHeight: Float,
38 | maxMonth: Float,
39 | animationProgress: Float,
40 | ) {
41 | if (data.tasks.isEmpty()) return
42 | val safeMaxMonth = max(maxMonth, 1f)
43 | val taskHeight = max(chartHeight / data.tasks.size, 1f)
44 |
45 | data.tasks.forEachIndexed { index, task ->
46 | val startX = chartLeft + (task.startMonth / safeMaxMonth) * chartWidth
47 | val width = max((task.duration / safeMaxMonth) * chartWidth * animationProgress, 1f)
48 | val y = chartTop + index * taskHeight
49 | val color =
50 | if (index < data.taskColors.size) {
51 | data.taskColors[index]
52 | } else {
53 | Color.Blue
54 | }
55 | drawScope.drawRect(
56 | color = color.copy(alpha = animationProgress),
57 | topLeft = Offset(startX, y + taskHeight * 0.1f),
58 | size = Size(width, max(taskHeight * 0.8f, 1f)),
59 | )
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/heatmap/HeatMapData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.heatmap
17 |
18 | import androidx.compose.ui.graphics.Color
19 | import kotlinx.datetime.Instant
20 |
21 | public data class ContributionData(
22 | val timestamp: Instant,
23 | val count: Int,
24 | )
25 |
26 | public data class ContributionHeatmapData(
27 | val contributions: List,
28 | val baseColor: Color = Color(0xFF40C463),
29 | val backgroundSquareColor: Color = Color(0xFF2D333B),
30 | )
31 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/heatmap/Heatmap.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.heatmap
17 |
18 | import androidx.compose.animation.core.Animatable
19 | import androidx.compose.animation.core.FastOutSlowInEasing
20 | import androidx.compose.animation.core.tween
21 | import androidx.compose.foundation.Canvas
22 | import androidx.compose.foundation.background
23 | import androidx.compose.foundation.horizontalScroll
24 | import androidx.compose.foundation.isSystemInDarkTheme
25 | import androidx.compose.foundation.layout.Box
26 | import androidx.compose.foundation.layout.fillMaxSize
27 | import androidx.compose.foundation.layout.padding
28 | import androidx.compose.foundation.rememberScrollState
29 | import androidx.compose.runtime.Composable
30 | import androidx.compose.runtime.LaunchedEffect
31 | import androidx.compose.runtime.remember
32 | import androidx.compose.ui.Modifier
33 | import androidx.compose.ui.graphics.Color
34 | import androidx.compose.ui.platform.LocalDensity
35 | import androidx.compose.ui.unit.dp
36 | import kotlinx.datetime.Clock
37 | import kotlinx.datetime.DateTimeUnit
38 | import kotlinx.datetime.TimeZone
39 | import kotlinx.datetime.atStartOfDayIn
40 | import kotlinx.datetime.minus
41 | import kotlinx.datetime.toLocalDateTime
42 |
43 | @Composable
44 | public fun Heatmap(
45 | renderer: HeatmapDataRenderer,
46 | modifier: Modifier = Modifier,
47 | isSystemInDarkTheme: Boolean = isSystemInDarkTheme(),
48 | ) {
49 | val density = LocalDensity.current
50 | val cellSize = with(density) { 8.dp.toPx() }
51 | val cellPadding = with(density) { 2.dp.toPx() }
52 |
53 | val now = Clock.System.now()
54 | val endDate = now.toLocalDateTime(TimeZone.currentSystemDefault()).date
55 | val startDate = endDate.minus(1, DateTimeUnit.YEAR)
56 |
57 | val startInstant = startDate.atStartOfDayIn(TimeZone.currentSystemDefault())
58 | val endInstant = endDate.atStartOfDayIn(TimeZone.currentSystemDefault())
59 |
60 | val animationProgress = remember { Animatable(0f) }
61 |
62 | LaunchedEffect(Unit) {
63 | animationProgress.animateTo(
64 | targetValue = 1f,
65 | animationSpec =
66 | tween(
67 | durationMillis = 1000,
68 | easing = FastOutSlowInEasing,
69 | ),
70 | )
71 | }
72 |
73 | Box(
74 | modifier =
75 | modifier
76 | .horizontalScroll(rememberScrollState())
77 | .background(if (isSystemInDarkTheme) Color.Black else Color.White)
78 | .padding(8.dp),
79 | ) {
80 | Canvas(
81 | modifier =
82 | Modifier
83 | .fillMaxSize()
84 | .padding(4.dp),
85 | ) {
86 | renderer.drawHeatmap(
87 | drawScope = this,
88 | cellSize = cellSize,
89 | cellPadding = cellPadding,
90 | startInstant = startInstant,
91 | endInstant = endInstant,
92 | animationProgress = animationProgress.value,
93 | isSystemInDarkTheme = isSystemInDarkTheme,
94 | )
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/heatmap/HeatmapDataRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.heatmap
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.geometry.Size
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import kotlinx.datetime.DateTimeUnit
23 | import kotlinx.datetime.Instant
24 | import kotlinx.datetime.TimeZone
25 | import kotlinx.datetime.daysUntil
26 | import kotlinx.datetime.plus
27 | import kotlinx.datetime.toLocalDateTime
28 |
29 | public interface HeatmapDataRenderer {
30 | public val data: ContributionHeatmapData
31 |
32 | public fun drawHeatmap(
33 | drawScope: DrawScope,
34 | cellSize: Float,
35 | cellPadding: Float,
36 | startInstant: Instant,
37 | endInstant: Instant,
38 | animationProgress: Float,
39 | isSystemInDarkTheme: Boolean,
40 | )
41 | }
42 |
43 | public class HeatmapRenderer(
44 | override val data: ContributionHeatmapData,
45 | ) : HeatmapDataRenderer {
46 | private fun getContributionColor(
47 | count: Int,
48 | isSystemInDarkTheme: Boolean,
49 | ): Color =
50 | when {
51 | count == 0 ->
52 | if (isSystemInDarkTheme) {
53 | Color(0xFF24292E)
54 | } else {
55 | Color(0xFFF6F8FA).copy(alpha = 0.5f)
56 | }
57 | count <= 3 -> data.baseColor.copy(alpha = 0.2f)
58 | count <= 6 -> data.baseColor.copy(alpha = 0.4f)
59 | count <= 9 -> data.baseColor.copy(alpha = 0.7f)
60 | else -> data.baseColor.copy(alpha = 1.0f)
61 | }
62 |
63 | override fun drawHeatmap(
64 | drawScope: DrawScope,
65 | cellSize: Float,
66 | cellPadding: Float,
67 | startInstant: Instant,
68 | endInstant: Instant,
69 | animationProgress: Float,
70 | isSystemInDarkTheme: Boolean,
71 | ) {
72 | with(drawScope) {
73 | val startDate = startInstant.toLocalDateTime(TimeZone.currentSystemDefault()).date
74 | val endDate = endInstant.toLocalDateTime(TimeZone.currentSystemDefault()).date
75 | val weeks = startDate.daysUntil(endDate) / 7
76 |
77 | val contributionsMap =
78 | data.contributions
79 | .groupingBy {
80 | it.timestamp.toLocalDateTime(TimeZone.currentSystemDefault()).date
81 | }.aggregate { _, accumulator: Int?, element, _ ->
82 | (accumulator ?: 0) + element.count
83 | }
84 |
85 | var currentDate = startDate
86 | for (week in 0..weeks) {
87 | for (dayOfWeek in 0..6) {
88 | if (currentDate <= endDate) {
89 | val contributions = contributionsMap[currentDate] ?: 0
90 |
91 | val x = week * (cellSize + cellPadding)
92 | val y = dayOfWeek * (cellSize + cellPadding)
93 |
94 | drawRect(
95 | color = getContributionColor(contributions, isSystemInDarkTheme),
96 | topLeft = Offset(x, y),
97 | size = Size(cellSize, cellSize),
98 | )
99 |
100 | currentDate = currentDate.plus(1, DateTimeUnit.DAY)
101 | }
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/lines/LineChartDataRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.lines
17 |
18 | import androidx.compose.ui.graphics.drawscope.DrawScope
19 |
20 | public interface LineChartDataRenderer {
21 | public fun getLabels(): List
22 |
23 | public fun calculateMaxValue(): Float
24 |
25 | public fun drawLines(
26 | drawScope: DrawScope,
27 | chartLeft: Float,
28 | chartTop: Float,
29 | chartWidth: Float,
30 | chartHeight: Float,
31 | maxValue: Float,
32 | animationProgress: Float,
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/lines/model/LineChartData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.lines.model
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | public interface LineChartData {
21 | public val labels: List
22 | }
23 |
24 | public data class SimpleLineChartData(
25 | override val labels: List,
26 | val values: List,
27 | val color: Color,
28 | ) : LineChartData
29 |
30 | public data class GroupedLineChartData(
31 | override val labels: List,
32 | val itemNames: List,
33 | val groupedValues: List>,
34 | val colors: List,
35 | ) : LineChartData
36 |
37 | public data class StackedLineChartData(
38 | override val labels: List,
39 | val stacks: List>,
40 | val colors: List,
41 | ) : LineChartData
42 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/lines/renderer/GroupedLineChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.lines.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.graphics.Color
20 | import androidx.compose.ui.graphics.drawscope.DrawScope
21 | import io.androidpoet.drafter.lines.LineChartDataRenderer
22 | import io.androidpoet.drafter.lines.model.GroupedLineChartData
23 | import kotlin.math.pow
24 |
25 | public class GroupedLineChartRenderer(
26 | private val data: GroupedLineChartData,
27 | ) : LineChartDataRenderer {
28 | override fun getLabels(): List = data.labels
29 |
30 | override fun calculateMaxValue(): Float = data.groupedValues.flatten().maxOrNull() ?: 0f
31 |
32 | override fun drawLines(
33 | drawScope: DrawScope,
34 | chartLeft: Float,
35 | chartTop: Float,
36 | chartWidth: Float,
37 | chartHeight: Float,
38 | maxValue: Float,
39 | animationProgress: Float,
40 | ) {
41 | val numPoints = data.labels.size
42 | val xPositions =
43 | List(numPoints) { index ->
44 | chartLeft + index * (chartWidth / (numPoints - 1))
45 | }
46 |
47 | data.itemNames.forEachIndexed { itemIndex, _ ->
48 | val points =
49 | List(numPoints) { index ->
50 | val value = data.groupedValues[index][itemIndex]
51 | val x = xPositions[index]
52 | val y = chartTop + chartHeight - (value / maxValue) * chartHeight
53 | Offset(x, y)
54 | }
55 |
56 | val totalLength =
57 | points
58 | .zipWithNext()
59 | .sumOf { (start, end) ->
60 | val dx = end.x - start.x
61 | val dy = end.y - start.y
62 | kotlin.math.sqrt((dx * dx + dy * dy).toDouble())
63 | }.toFloat()
64 |
65 | var currentLength = 0f
66 |
67 | points.zipWithNext().forEach { (start, end) ->
68 | val segmentLength =
69 | kotlin.math.sqrt(
70 | (end.x - start.x).pow(2) + (end.y - start.y).pow(2),
71 | )
72 | val segmentProgress = (currentLength + segmentLength) / totalLength
73 |
74 | if (segmentProgress <= animationProgress) {
75 | drawScope.drawLine(
76 | color = data.colors.getOrElse(itemIndex) { Color.Gray },
77 | start = start,
78 | end = end,
79 | strokeWidth = 2f,
80 | )
81 | } else if (currentLength / totalLength <= animationProgress) {
82 | val remainingProgress =
83 | (animationProgress - currentLength / totalLength) / (segmentLength / totalLength)
84 | val partialEnd =
85 | Offset(
86 | x = start.x + (end.x - start.x) * remainingProgress,
87 | y = start.y + (end.y - start.y) * remainingProgress,
88 | )
89 | drawScope.drawLine(
90 | color = data.colors.getOrElse(itemIndex) { Color.Gray },
91 | start = start,
92 | end = partialEnd,
93 | strokeWidth = 2f,
94 | )
95 | }
96 | currentLength += segmentLength
97 | }
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/lines/renderer/LineChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.lines.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.graphics.drawscope.DrawScope
20 | import io.androidpoet.drafter.lines.LineChartDataRenderer
21 | import io.androidpoet.drafter.lines.model.SimpleLineChartData
22 | import kotlin.math.pow
23 |
24 | public class LineChartRenderer(
25 | private val data: SimpleLineChartData,
26 | ) : LineChartDataRenderer {
27 | override fun getLabels(): List = data.labels
28 |
29 | override fun calculateMaxValue(): Float = data.values.maxOrNull() ?: 0f
30 |
31 | override fun drawLines(
32 | drawScope: DrawScope,
33 | chartLeft: Float,
34 | chartTop: Float,
35 | chartWidth: Float,
36 | chartHeight: Float,
37 | maxValue: Float,
38 | animationProgress: Float,
39 | ) {
40 | val points =
41 | data.values.mapIndexed { index, value ->
42 | val x = chartLeft + index * (chartWidth / (data.values.size - 1))
43 | val y = chartTop + chartHeight - (value / maxValue) * chartHeight
44 | Offset(x, y)
45 | }
46 |
47 | val totalLength =
48 | points
49 | .zipWithNext()
50 | .sumOf { (start, end) ->
51 | val dx = end.x - start.x
52 | val dy = end.y - start.y
53 | kotlin.math.sqrt((dx * dx + dy * dy).toDouble())
54 | }.toFloat()
55 |
56 | var currentLength = 0f
57 | var lastDrawnPoint = points.first()
58 |
59 | points.zipWithNext().forEach { (start, end) ->
60 | val segmentLength =
61 | kotlin.math.sqrt(
62 | (end.x - start.x).pow(2) + (end.y - start.y).pow(2),
63 | )
64 | val segmentProgress = (currentLength + segmentLength) / totalLength
65 |
66 | if (segmentProgress <= animationProgress) {
67 | drawScope.drawLine(
68 | color = data.color,
69 | start = start,
70 | end = end,
71 | strokeWidth = 2f,
72 | )
73 | lastDrawnPoint = end
74 | } else if (currentLength / totalLength <= animationProgress) {
75 | val remainingProgress =
76 | (animationProgress - currentLength / totalLength) / (segmentLength / totalLength)
77 | val partialEnd =
78 | Offset(
79 | x = start.x + (end.x - start.x) * remainingProgress,
80 | y = start.y + (end.y - start.y) * remainingProgress,
81 | )
82 | drawScope.drawLine(
83 | color = data.color,
84 | start = start,
85 | end = partialEnd,
86 | strokeWidth = 2f,
87 | )
88 | }
89 | currentLength += segmentLength
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/lines/renderer/StackedLineChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.lines.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.graphics.Color
20 | import androidx.compose.ui.graphics.Path
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import androidx.compose.ui.graphics.drawscope.Fill
23 | import io.androidpoet.drafter.lines.LineChartDataRenderer
24 | import io.androidpoet.drafter.lines.model.StackedLineChartData
25 |
26 | public class StackedLineChartRenderer(
27 | private val data: StackedLineChartData,
28 | ) : LineChartDataRenderer {
29 | override fun getLabels(): List = data.labels
30 |
31 | override fun calculateMaxValue(): Float = data.stacks.map { it.sum() }.maxOrNull() ?: 0f
32 |
33 | override fun drawLines(
34 | drawScope: DrawScope,
35 | chartLeft: Float,
36 | chartTop: Float,
37 | chartWidth: Float,
38 | chartHeight: Float,
39 | maxValue: Float,
40 | animationProgress: Float,
41 | ) {
42 | val numPoints = data.labels.size
43 | val xPositions =
44 | List(numPoints) { index ->
45 | chartLeft + index * (chartWidth / (numPoints - 1))
46 | }
47 |
48 | val accumulatedValues = MutableList(numPoints) { 0f }
49 | val stackCount = data.stacks[0].size
50 | for (stackIndex in 0 until stackCount) {
51 | val previousAccumulatedValues = accumulatedValues.toList()
52 | for (i in 0 until numPoints) {
53 | accumulatedValues[i] += data.stacks[i][stackIndex]
54 | }
55 | val upperPoints =
56 | List(numPoints) { i ->
57 | val x = xPositions[i]
58 | val y =
59 | chartTop + chartHeight -
60 | ((accumulatedValues[i] * animationProgress) / maxValue) * chartHeight
61 | Offset(x, y)
62 | }
63 |
64 | val lowerPoints =
65 | List(numPoints) { i ->
66 | val x = xPositions[i]
67 | val y =
68 | chartTop + chartHeight -
69 | ((previousAccumulatedValues[i] * animationProgress) / maxValue) * chartHeight
70 | Offset(x, y)
71 | }
72 | val path =
73 | Path().apply {
74 | moveTo(upperPoints.first().x, upperPoints.first().y)
75 | for (point in upperPoints.drop(1)) {
76 | lineTo(point.x, point.y)
77 | }
78 | for (point in lowerPoints.reversed()) {
79 | lineTo(point.x, point.y)
80 | }
81 | close()
82 | }
83 | drawScope.drawPath(
84 | path = path,
85 | color = data.colors.getOrElse(stackIndex) { Color.Gray },
86 | style = Fill,
87 | )
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/pie/PieChart.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.pie
17 |
18 | import androidx.compose.animation.core.Animatable
19 | import androidx.compose.animation.core.tween
20 | import androidx.compose.foundation.Canvas
21 | import androidx.compose.foundation.isSystemInDarkTheme
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.runtime.LaunchedEffect
24 | import androidx.compose.runtime.remember
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.text.rememberTextMeasurer
27 | import io.androidpoet.drafter.pie.renderer.PieChartDataRenderer
28 |
29 | @Composable
30 | public fun PieChart(
31 | renderer: PieChartDataRenderer,
32 | modifier: Modifier = Modifier,
33 | animate: Boolean = true,
34 | isSystemInDarkTheme: Boolean = isSystemInDarkTheme(),
35 | ) {
36 | val textMeasurer = rememberTextMeasurer()
37 | val progress = remember { Animatable(0f) }
38 | LaunchedEffect(animate) {
39 | if (animate) {
40 | progress.animateTo(
41 | targetValue = 1f,
42 | animationSpec = tween(durationMillis = 1000),
43 | )
44 | } else {
45 | progress.snapTo(1f)
46 | }
47 | }
48 | Canvas(modifier = modifier) {
49 | renderer.drawChart(
50 | drawScope = this,
51 | size = size,
52 | progress = progress.value,
53 | textMeasurer = textMeasurer,
54 | isSystemInDarkTheme = isSystemInDarkTheme,
55 | )
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/pie/model/PieChartData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.pie.model
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | public data class PieChartData(
21 | val slices: List,
22 | ) {
23 | public data class Slice(
24 | val value: Float,
25 | val color: Color,
26 | val label: String,
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/pie/renderer/DonutChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.pie.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.geometry.Size
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import androidx.compose.ui.graphics.drawscope.Stroke
23 | import androidx.compose.ui.text.TextMeasurer
24 | import androidx.compose.ui.text.TextStyle
25 | import androidx.compose.ui.text.drawText
26 | import androidx.compose.ui.unit.sp
27 | import io.androidpoet.drafter.pie.model.PieChartData
28 | import kotlin.math.PI
29 | import kotlin.math.cos
30 | import kotlin.math.max
31 | import kotlin.math.sin
32 |
33 | /**
34 | * Renders a "donut" by using an arc + Stroke (hole in center).
35 | */
36 | public class DonutChartRenderer(
37 | override val data: PieChartData,
38 | private val labelThreshold: Float = 5f,
39 | private val holeRadiusFraction: Float = 0.5f,
40 | ) : PieChartDataRenderer {
41 | public override fun drawChart(
42 | drawScope: DrawScope,
43 | size: Size,
44 | progress: Float,
45 | textMeasurer: TextMeasurer,
46 | isSystemInDarkTheme: Boolean,
47 | ) {
48 | val totalValue =
49 | max(
50 | data.slices.sumOf { slice -> slice.value.toDouble() }.toFloat(),
51 | 1f,
52 | )
53 | var startAngle = -90f
54 |
55 | val outerRadius = (size.minDimension / 2) * 0.6f
56 | val innerRadius = outerRadius * holeRadiusFraction
57 | val center = Offset(size.width / 2, size.height / 2)
58 |
59 | data.slices.forEach { slice ->
60 | val slicePercentage = slice.value / totalValue
61 | val sweepAngle = slicePercentage * 360f * progress
62 | drawScope.drawArc(
63 | color = slice.color,
64 | startAngle = startAngle,
65 | sweepAngle = sweepAngle,
66 | useCenter = false,
67 | topLeft = Offset(center.x - outerRadius, center.y - outerRadius),
68 | size = Size(outerRadius * 2, outerRadius * 2),
69 | style = Stroke(width = outerRadius - innerRadius),
70 | )
71 | val percentage = slicePercentage * 100
72 | if (percentage >= labelThreshold && sweepAngle > 0f) {
73 | val midAngleRad = (startAngle + sweepAngle / 2) * (PI.toFloat() / 180f)
74 | val labelRadius = outerRadius * 1.3f
75 |
76 | val labelText = "${percentage.toInt()}%"
77 | val style =
78 | TextStyle(fontSize = 12.sp, color = if (isSystemInDarkTheme) Color.White else Color.Black)
79 | val textLayout = textMeasurer.measure(labelText, style)
80 | val baseX = center.x + (labelRadius * cos(midAngleRad))
81 | val baseY = center.y + (labelRadius * sin(midAngleRad))
82 | val xOffset = -textLayout.size.width / 2
83 | val yOffset = -textLayout.size.height / 2
84 | val radialPushFactor = 0.15f // Adjust this value to control how far text pushes outward
85 | val radialOffsetX = radialPushFactor * labelRadius * cos(midAngleRad)
86 | val radialOffsetY = radialPushFactor * labelRadius * sin(midAngleRad)
87 |
88 | drawScope.drawText(
89 | textMeasurer = textMeasurer,
90 | text = labelText,
91 | style = style,
92 | topLeft =
93 | Offset(
94 | x = baseX + xOffset + radialOffsetX,
95 | y = baseY + yOffset + radialOffsetY,
96 | ),
97 | )
98 | }
99 |
100 | startAngle += sweepAngle
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/pie/renderer/PieChartDataRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.pie.renderer
17 |
18 | import androidx.compose.ui.geometry.Size
19 | import androidx.compose.ui.graphics.drawscope.DrawScope
20 | import androidx.compose.ui.text.TextMeasurer
21 | import io.androidpoet.drafter.pie.model.PieChartData
22 |
23 | /**
24 | * A single interface for all pie/donut chart renderers.
25 | * - [data] stores the PieChartData internally.
26 | * - [drawChart] is called by [PieChart] composable to do the drawing.
27 | */
28 | public interface PieChartDataRenderer {
29 | public val data: PieChartData
30 |
31 | /**
32 | * Draw the chart (pie, donut, etc.).
33 | * @param drawScope current [DrawScope] to use for drawing.
34 | * @param size The canvas size.
35 | * @param progress A float [0..1] that can be used for animation.
36 | */
37 | public fun drawChart(
38 | drawScope: DrawScope,
39 | size: Size,
40 | progress: Float,
41 | textMeasurer: TextMeasurer,
42 | isSystemInDarkTheme: Boolean,
43 | )
44 | }
45 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/pie/renderer/PieChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.pie.renderer
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.geometry.Size
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.drawscope.DrawScope
22 | import androidx.compose.ui.text.TextMeasurer
23 | import androidx.compose.ui.text.TextStyle
24 | import androidx.compose.ui.text.drawText
25 | import androidx.compose.ui.text.font.FontWeight
26 | import androidx.compose.ui.unit.sp
27 | import io.androidpoet.drafter.pie.model.PieChartData
28 | import kotlin.math.PI
29 | import kotlin.math.cos
30 | import kotlin.math.max
31 | import kotlin.math.sin
32 |
33 | public class PieChartRenderer(
34 | override val data: PieChartData,
35 | private val labelThreshold: Float = 5f,
36 | ) : PieChartDataRenderer {
37 | public override fun drawChart(
38 | drawScope: DrawScope,
39 | size: Size,
40 | progress: Float,
41 | textMeasurer: TextMeasurer,
42 | isSystemInDarkTheme: Boolean,
43 | ) {
44 | val totalValue =
45 | max(
46 | data.slices.sumOf { slice -> slice.value.toDouble() }.toFloat(),
47 | 1f,
48 | )
49 |
50 | var startAngle = -90f
51 | val radius = (size.minDimension / 2) * 0.7f
52 | val center = Offset(size.width / 2, size.height / 2)
53 |
54 | data.slices.forEach { slice ->
55 | val slicePercentage = slice.value / totalValue
56 | val sweepAngle = slicePercentage * 360f * progress
57 |
58 | drawScope.drawArc(
59 | color = slice.color,
60 | startAngle = startAngle,
61 | sweepAngle = sweepAngle,
62 | useCenter = true,
63 | topLeft = Offset(center.x - radius, center.y - radius),
64 | size = Size(radius * 2, radius * 2),
65 | )
66 | val percentage = slicePercentage * 100
67 | if (percentage >= labelThreshold && sweepAngle > 0f) {
68 | val angleMid = startAngle + sweepAngle / 2
69 | val angleRad = angleMid * (PI / 180)
70 | val labelRadius = radius * 0.7f
71 | val labelX = center.x + (labelRadius * cos(angleRad)).toFloat()
72 | val labelY = center.y + (labelRadius * sin(angleRad)).toFloat()
73 |
74 | val labelText = "${percentage.toInt()}%"
75 | val style =
76 | TextStyle(
77 | fontSize = 12.sp,
78 | color = if (isSystemInDarkTheme) Color.Black else Color.White,
79 | fontWeight = FontWeight.Bold,
80 | )
81 | val textLayout = textMeasurer.measure(labelText, style)
82 |
83 | drawScope.drawText(
84 | textMeasurer = textMeasurer,
85 | text = labelText,
86 | style = style,
87 | topLeft =
88 | Offset(
89 | x = labelX - textLayout.size.width / 2,
90 | y = labelY - textLayout.size.height / 2,
91 | ),
92 | )
93 | }
94 |
95 | startAngle += sweepAngle
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/popup/Tooltip.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.popup
17 |
18 | import androidx.compose.foundation.layout.padding
19 | import androidx.compose.foundation.shape.RoundedCornerShape
20 | import androidx.compose.material3.Surface
21 | import androidx.compose.material3.Text
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Alignment
24 | import androidx.compose.ui.Modifier
25 | import androidx.compose.ui.draw.shadow
26 | import androidx.compose.ui.geometry.Offset
27 | import androidx.compose.ui.graphics.Color
28 | import androidx.compose.ui.unit.dp
29 | import androidx.compose.ui.unit.sp
30 | import androidx.compose.ui.window.Popup
31 |
32 | @Composable
33 | public fun Tooltip(text: String) {
34 | Popup(
35 | alignment = Alignment.TopStart,
36 | ) {
37 | Surface(
38 | modifier =
39 | Modifier
40 | .shadow(4.dp)
41 | .padding(4.dp),
42 | color = Color.White,
43 | shape = RoundedCornerShape(4.dp),
44 | ) {
45 | Text(
46 | text = text,
47 | modifier = Modifier.padding(8.dp),
48 | fontSize = 12.sp,
49 | )
50 | }
51 | }
52 | }
53 |
54 | public data class HoverState(
55 | val isHovered: Boolean = false,
56 | val position: Offset = Offset.Zero,
57 | val value: String = "",
58 | )
59 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/radar/RadarChart.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.radar
17 |
18 | import androidx.compose.animation.core.Animatable
19 | import androidx.compose.animation.core.FastOutSlowInEasing
20 | import androidx.compose.animation.core.tween
21 | import androidx.compose.foundation.Canvas
22 | import androidx.compose.foundation.isSystemInDarkTheme
23 | import androidx.compose.foundation.layout.size
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.runtime.LaunchedEffect
26 | import androidx.compose.runtime.remember
27 | import androidx.compose.ui.Modifier
28 | import androidx.compose.ui.text.rememberTextMeasurer
29 | import androidx.compose.ui.unit.dp
30 | import io.androidpoet.drafter.radar.renderer.RadarChartRenderer
31 |
32 | @Composable
33 | public fun RadarChart(
34 | renderer: RadarChartRenderer,
35 | modifier: Modifier = Modifier,
36 | isSystemInDarkTheme: Boolean = isSystemInDarkTheme(),
37 | ) {
38 | val textMeasurer = rememberTextMeasurer()
39 | val animatedProgress = remember { Animatable(0f) }
40 |
41 | LaunchedEffect(Unit) {
42 | animatedProgress.animateTo(
43 | targetValue = 1f,
44 | animationSpec =
45 | tween(
46 | durationMillis = 1000,
47 | easing = FastOutSlowInEasing,
48 | ),
49 | )
50 | }
51 |
52 | Canvas(modifier = modifier.size(300.dp)) {
53 | val centerX = size.width / 2
54 | val centerY = size.height / 2
55 | val radius = size.width.coerceAtMost(size.height) / 2 * 0.8f
56 |
57 | renderer.drawChart(
58 | drawScope = this,
59 | centerX = centerX,
60 | centerY = centerY,
61 | radius = radius,
62 | textMeasurer = textMeasurer,
63 | animationProgress = animatedProgress.value,
64 | isSystemInDarkTheme = isSystemInDarkTheme,
65 | )
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/radar/RadarChartDataRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.radar
17 |
18 | import androidx.compose.ui.graphics.drawscope.DrawScope
19 | import androidx.compose.ui.text.TextMeasurer
20 |
21 | public interface RadarChartDataRenderer {
22 | public fun drawChart(
23 | drawScope: DrawScope,
24 | centerX: Float,
25 | centerY: Float,
26 | radius: Float,
27 | textMeasurer: TextMeasurer,
28 | animationProgress: Float,
29 | isSystemInDarkTheme: Boolean,
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/radar/model/RadarChartData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.radar.model
17 |
18 | public data class RadarChartData(
19 | val values: Map,
20 | )
21 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/scatterplot/ScatterPlotChartRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.scatterplot
17 |
18 | import androidx.compose.ui.geometry.Offset
19 | import androidx.compose.ui.graphics.Color
20 | import androidx.compose.ui.graphics.drawscope.DrawScope
21 | import io.androidpoet.drafter.scatterplot.model.ScatterPlotData
22 |
23 | public interface ScatterPlotRenderer {
24 | public fun calculateMaxValues(): Pair
25 |
26 | public fun getPoints(): List>
27 |
28 | public fun drawPoints(
29 | drawScope: DrawScope,
30 | chartLeft: Float,
31 | chartTop: Float,
32 | chartWidth: Float,
33 | chartHeight: Float,
34 | maxX: Float,
35 | maxY: Float,
36 | animationProgress: Float,
37 | )
38 | }
39 |
40 | public class SimpleScatterPlotRenderer(
41 | public val data: ScatterPlotData,
42 | ) : ScatterPlotRenderer {
43 | override fun calculateMaxValues(): Pair {
44 | val maxX = data.points.maxOfOrNull { it.first } ?: 0f
45 | val maxY = data.points.maxOfOrNull { it.second } ?: 0f
46 | return Pair(maxX, maxY)
47 | }
48 |
49 | override fun getPoints(): List> = data.points
50 |
51 | override fun drawPoints(
52 | drawScope: DrawScope,
53 | chartLeft: Float,
54 | chartTop: Float,
55 | chartWidth: Float,
56 | chartHeight: Float,
57 | maxX: Float,
58 | maxY: Float,
59 | animationProgress: Float,
60 | ) {
61 | data.points.forEachIndexed { index, point ->
62 | val x = chartLeft + (point.first / maxX) * chartWidth
63 | val y = chartTop + chartHeight - (point.second / maxY) * chartHeight
64 |
65 | val pointSize = 5f * animationProgress
66 |
67 | val color =
68 | if (index < data.pointColors.size) data.pointColors[index] else Color.Gray
69 | drawScope.drawCircle(
70 | color = color.copy(alpha = animationProgress),
71 | radius = pointSize,
72 | center = Offset(x, y),
73 | )
74 | }
75 | }
76 | }
77 |
78 | public fun DrawScope.drawAxes(
79 | left: Float,
80 | top: Float,
81 | bottom: Float,
82 | width: Float,
83 | isSystemInDarkTheme: Boolean,
84 | ) {
85 | drawLine(
86 | if (isSystemInDarkTheme) Color.White else Color.Black,
87 | Offset(left, top),
88 | Offset(left, bottom),
89 | strokeWidth = 2f,
90 | )
91 | drawLine(
92 | if (isSystemInDarkTheme) Color.White else Color.Black,
93 | Offset(left, bottom),
94 | Offset(left + width, bottom),
95 | strokeWidth = 2f,
96 | )
97 | }
98 |
--------------------------------------------------------------------------------
/drafter/src/commonMain/kotlin/io/androidpoet/drafter/scatterplot/model/ScatterPlotData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.androidpoet.drafter.scatterplot.model
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | public data class ScatterPlotData(
21 | val points: List>,
22 | val pointColors: List = listOf(Color.Black),
23 | )
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | # https://docs.gradle.org/current/userguide/build_environment.html#sec:configuring_jvm_memory
17 | org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC -Dlint.nullness.ignore-deprecated=true
18 | # https://docs.gradle.org/current/userguide/build_cache.html
19 | org.gradle.caching=true
20 | # When configured, Gradle will run in incubating parallel mode.
21 | # This option should only be used with decoupled projects. More details, visit
22 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
23 | org.gradle.parallel=true
24 | # Configure only necessary projects, useful with multimodule projects
25 | org.gradle.configureondemand=true
26 | # AndroidX Migration https://developer.android.com/jetpack/androidx/migrate
27 | android.useAndroidX=true
28 | # Removes uneccessary default build features
29 | android.defaults.buildfeatures.aidl=false
30 | android.defaults.buildfeatures.buildconfig=false
31 | android.defaults.buildfeatures.renderscript=false
32 | android.defaults.buildfeatures.resvalues=false
33 | android.defaults.buildfeatures.shaders=false
34 | # Enables namespacing of each library's R class so that its R class includes only the
35 | # resources declared in the library itself and none from the library's dependencies,
36 | # thereby reducing the size of the R class for that library
37 | # https://developer.android.com/studio/releases/gradle-plugin#4.1-nontransitive-r-class
38 | android.nonTransitiveRClass=true
39 | # MPP
40 | kotlin.mpp.enableCInteropCommonization=true
41 | kotlin.mpp.stability.nowarn=true
42 | kotlin.mpp.androidSourceSetLayoutVersion=2
43 | kotlin.native.binary.memoryModel=experimental
44 | kotlin.native.cacheKind=none
45 | # Compose
46 | org.jetbrains.compose.experimental.uikit.enabled=true
47 | org.jetbrains.compose.experimental.macos.enabled=true
48 | org.jetbrains.compose.experimental.jscanvas.enabled=true
49 | compose.kotlin.native.manageCacheKind=false
50 | # Required to publish to Nexus (see https://github.com/gradle/gradle/issues/11308)
51 | systemProp.org.gradle.internal.publish.checksums.insecure=true
52 | # Increase timeout when pushing to Sonatype (otherwise we get timeouts)
53 | systemProp.org.gradle.internal.http.socketTimeout=120000
54 | POM_URL=https://github.com/androidpoet/Drafter
55 | POM_SCM_URL=https://github.com/androidpoet/Drafter
56 | POM_SCM_CONNECTION=scm:git:git://github.com/androidpoet/Drafter.git
57 | POM_SCM_DEV_CONNECTION=scm:git:git://github.com/androidpoet/Drafter.git
58 | POM_LICENCE_NAME=The Apache Software License, Version 2.0
59 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
60 | POM_LICENCE_DIST=repo
61 | POM_DEVELOPER_ID=androidpoet
62 | POM_DEVELOPER_NAME=Ranbir Singh
63 | POM_DEVELOPER_URL=https://github.com/androidpoet/
64 | POM_DEVELOPER_EMAIL=poetdroid2@gmail.com
65 | SONATYPE_HOST=CENTRAL_PORTAL
66 | RELEASE_SIGNING_ENABLED=true
67 | SONATYPE_AUTOMATIC_RELEASE=true
68 | SONATYPE_CONNECT_TIMEOUT_SECONDS=60
69 | SONATYPE_CLOSE_TIMEOUT_SECONDS=900
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | agp = "8.5.2"
3 | dokka = "1.9.10"
4 | kotlinxDatetime = "0.6.1"
5 | nexusPlugin = "0.29.0"
6 | kotlin = "2.0.20"
7 | kotlinBinaryCompatibility = "0.16.3"
8 | jvmTarget = "11"
9 | androidxComposeBom = "2024.05.00"
10 | androidxActivity = "1.9.2"
11 | androidxTest = "1.6.2"
12 | baselineProfiles = "1.3.1"
13 | uiAutomator = "2.3.0"
14 | spotless = "6.21.0"
15 | androidxMacroBenchmark = "1.3.0"
16 | jetbrains-compose = "1.6.11"
17 |
18 | [plugins]
19 | android-application = { id = "com.android.application", version.ref = "agp" }
20 | android-library = { id = "com.android.library", version.ref = "agp" }
21 | android-test = { id = "com.android.test", version.ref = "agp" }
22 | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
23 | kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
24 | compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
25 | dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
26 | nexus-plugin = { id = "com.vanniktech.maven.publish", version.ref = "nexusPlugin" }
27 | kotlin-binary-compatibility = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "kotlinBinaryCompatibility" }
28 | spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
29 | baseline-profile = { id = "androidx.baselineprofile", version.ref = "androidxMacroBenchmark" }
30 | jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "jetbrains-compose" }
31 |
32 | [libraries]
33 | androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }
34 | androidx-compose-ui = { group = "androidx.compose.animation", name = "animation" }
35 | androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
36 | androidx-compose-material = { group = "androidx.compose.material", name = "material" }
37 | androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
38 | androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
39 | androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
40 | androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
41 | # unit test
42 | androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTest" }
43 | androidx-profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version.ref = "baselineProfiles" }
44 | androidx-benchmark-macro = { module = "androidx.benchmark:benchmark-macro-junit4", version.ref = "androidxMacroBenchmark" }
45 | androidx-test-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version.ref = "uiAutomator" }
46 | kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidPoet/Drafter/b2cd0f60940dceddc88b0976d063ca45cd7871f4/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo. 1>&2
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
48 | echo. 1>&2
49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
50 | echo location of your Java installation. 1>&2
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo. 1>&2
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
62 | echo. 1>&2
63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
64 | echo location of your Java installation. 1>&2
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ],
6 | "packageRules": [
7 | {
8 | "groupName": "Kotlin, KSP and Compose Compiler",
9 | "groupSlug": "kotlin",
10 | "matchPackagePrefixes": [
11 | "com.google.devtools.ksp",
12 | "androidx.compose.compiler",
13 | "com.android.tools.build:gradle"
14 | ],
15 | "matchPackagePatterns": [
16 | "org.jetbrains.kotlin.*"
17 | ],
18 | "enabled": false
19 | },
20 | {
21 | "description": "Automatically merge minor and patch-level updates",
22 | "matchUpdateTypes": ["minor", "patch", "digest"],
23 | "automerge": true,
24 | "automergeType": "pr",
25 | "platformAutomerge": true
26 | },
27 | {
28 | "description": "Exclude Spotless updates",
29 | "matchPackagePrefixes": ["com.diffplug.spotless"],
30 | "enabled": false
31 | }
32 | ]
33 | }
34 |
--------------------------------------------------------------------------------
/scripts/publish-module.gradle.kts:
--------------------------------------------------------------------------------
1 | import io.androidpoet.drafter.Configuration
2 |
3 | apply(plugin = "com.vanniktech.maven.publish")
4 |
5 | rootProject.extra.apply {
6 | val snapshot = System.getenv("SNAPSHOT").toBoolean()
7 | val libVersion =
8 | if (snapshot) {
9 | Configuration.snapshotVersionName
10 | } else {
11 | Configuration.versionName
12 | }
13 | set("libVersion", libVersion)
14 | }
15 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | maven(url = "https://plugins.gradle.org/m2/")
7 | maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev")
8 | }
9 | }
10 | dependencyResolutionManagement {
11 | repositories {
12 | google()
13 | mavenCentral()
14 | maven(url = "https://plugins.gradle.org/m2/")
15 | maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev")
16 | }
17 | }
18 | rootProject.name = "DrafterDemo"
19 | include(":app")
20 | include(":drafter")
21 | include(":baselineprofile-app")
22 | include(":baselineprofile")
23 |
--------------------------------------------------------------------------------
/spotless/copyright.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
--------------------------------------------------------------------------------
/spotless/copyright.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Designed and developed by 2024 androidpoet (Ranbir Singh)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
--------------------------------------------------------------------------------
/spotless/copyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
--------------------------------------------------------------------------------