├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── workflows │ ├── deploy-docs.yml │ └── static-check.yml ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── AndroidProjectSystem.xml ├── artifacts │ ├── sample_desktop.xml │ └── sample_wasm_js.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── copyright │ └── Charty.xml ├── deploymentTargetSelector.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml ├── migrations.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── build.gradle.kts ├── charty ├── build.gradle.kts ├── detekt.yml ├── gradle.properties └── src │ └── commonMain │ └── kotlin │ └── com │ └── himanshoe │ └── charty │ ├── bar │ ├── BarChart.kt │ ├── ComparisonBarChart.kt │ ├── HorizontalBarChart.kt │ ├── LineBarChart.kt │ ├── LineStackBarChart.kt │ ├── SignalBarChart.kt │ ├── StackBarChart.kt │ ├── StorageBar.kt │ ├── config │ │ ├── BarChartColorConfig.kt │ │ ├── BarChartConfig.kt │ │ ├── BarTooltip.kt │ │ ├── ComparisonBarChartConfig.kt │ │ ├── HorizontalBarLabelConfig.kt │ │ └── StackBarConfig.kt │ ├── model │ │ ├── BarData.kt │ │ ├── ComparisonBarData.kt │ │ ├── StackBarData.kt │ │ └── StorageData.kt │ └── modifier │ │ └── ModifierExt.kt │ ├── circle │ ├── CircleChart.kt │ ├── SpeedometerProgressBar.kt │ ├── config │ │ ├── CircleChartConfig.kt │ │ └── DotConfig.kt │ └── model │ │ ├── CircleData.kt │ │ └── StartingPosition.kt │ ├── common │ ├── CanvasExt.kt │ ├── ChartColor.kt │ ├── LabelConfig.kt │ ├── TargetConfig.kt │ └── TextConfig.kt │ ├── line │ ├── LineChart.kt │ ├── MutliLineChart.kt │ ├── config │ │ ├── LineChartColorConfig.kt │ │ └── LineChartConfig.kt │ ├── ext │ │ ├── LineChartCanvasExt.kt │ │ └── ModifierExt.kt │ └── model │ │ ├── LineData.kt │ │ └── MultiLineData.kt │ ├── pie │ ├── PieChart.kt │ └── model │ │ └── PieChartData.kt │ └── point │ ├── PointChart.kt │ ├── model │ ├── PointChartColorConfig.kt │ ├── PointChartConfig.kt │ └── PointData.kt │ └── modifier │ └── ModifierExt.kt ├── docs ├── charts │ ├── bar_chart.md │ ├── circle_chart.md │ ├── comparison_bar_chart.md │ ├── horizontal_bar_chart.md │ ├── line_bar_chart.md │ ├── line_chart.md │ ├── line_stack_bar_chart.md │ ├── multi_line_chart.md │ ├── pie_chart.md │ ├── point_chart.md │ ├── signal_bar_chart.md │ ├── speedometer_progress_bar.md │ ├── stack_bar_chart.md │ └── storage_bar.md ├── index.md └── site │ ├── 404.html │ ├── __init__.py │ ├── base.html │ ├── content.html │ ├── css │ ├── base.css │ ├── base.min.css │ ├── bootstrap-custom.css │ ├── bootstrap-custom.min.css │ ├── cinder.css │ ├── cinder.min.css │ ├── highlight.css │ └── highlight.min.css │ ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff │ ├── img │ ├── banner.png │ ├── bar │ │ ├── barchart_01.png │ │ ├── comparisonchart_01.png │ │ ├── horizontalChart_01.png │ │ ├── horizontalChart_02.png │ │ ├── lineChart_01.png │ │ ├── line_stack_bar_chart_01.png │ │ ├── stack_bar_chart_01.png │ │ └── storagebar.png │ ├── circle │ │ └── circleChart_01.png │ ├── line │ │ ├── linechart_02.png │ │ ├── linechart_03.png │ │ ├── linechart_04.png │ │ ├── multiple_line_01.png │ │ └── multiple_line_02.png │ ├── pie │ │ └── piechart_01.png │ ├── point │ │ └── pointChart_01.png │ ├── signalbar.png │ └── speedometer.png │ ├── js │ ├── base.js │ └── bootstrap-3.0.3.min.js │ ├── keyboard-modal.html │ ├── main.html │ ├── mkdocs_theme.yml │ ├── nav-sub.html │ ├── nav.html │ ├── search-modal.html │ └── toc.html ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── img ├── banner.png ├── photos │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ └── 6.png └── video │ ├── android.mp4 │ └── ios.mp4 ├── iosApp ├── Configuration │ └── Config.xcconfig ├── iosApp.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcuserdata │ │ │ └── himanshoe.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── himanshoe.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── iosApp │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── app-icon-1024.png │ └── Contents.json │ ├── ContentView.swift │ ├── Info.plist │ ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json │ └── iOSApp.swift ├── mkdocs.yml ├── renovate.json ├── sample ├── build.gradle.kts └── src │ ├── androidMain │ ├── AndroidManifest.xml │ ├── kotlin │ │ └── com │ │ │ └── himanshoe │ │ │ └── sample │ │ │ ├── MainActivity.kt │ │ │ └── Platform.android.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.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ └── strings.xml │ ├── commonMain │ ├── composeResources │ │ └── drawable │ │ │ └── compose-multiplatform.xml │ └── kotlin │ │ └── com │ │ └── himanshoe │ │ └── sample │ │ ├── App.kt │ │ ├── Greeting.kt │ │ └── Platform.kt │ ├── desktopMain │ └── kotlin │ │ └── com │ │ └── himanshoe │ │ └── sample │ │ ├── Platform.jvm.kt │ │ └── main.kt │ ├── iosMain │ └── kotlin │ │ └── com │ │ └── himanshoe │ │ └── sample │ │ ├── MainViewController.kt │ │ └── Platform.ios.kt │ └── wasmJsMain │ ├── kotlin │ └── com │ │ └── himanshoe │ │ └── sample │ │ ├── Platform.wasmJs.kt │ │ └── main.kt │ └── resources │ ├── index.html │ └── styles.css └── settings.gradle.kts /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [hi-manshu] 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Desktop (please complete the following information):** 28 | 29 | - OS: [e.g. iOS] 30 | - Browser [e.g. chrome, safari] 31 | - Version [e.g. 22] 32 | 33 | **Smartphone (please complete the following information):** 34 | 35 | - Device: [e.g. iPhone6] 36 | - OS: [e.g. iOS8.1] 37 | - Browser [e.g. stock browser, safari] 38 | - Version [e.g. 22] 39 | 40 | **Additional context** 41 | Add any other context about the problem here. 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Documentation 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' # Trigger on any tag 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write # Needed to deploy to gh-pages 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 # Fetch all history for all tags and branches 18 | 19 | - name: Set up Python 20 | uses: actions/setup-python@v5 21 | with: 22 | python-version: '3.x' 23 | 24 | - name: Install dependencies 25 | run: | 26 | pip install mkdocs 27 | 28 | - name: Build documentation 29 | run: mkdocs build 30 | 31 | - name: Deploy to GitHub Pages 32 | run: mkdocs gh-deploy --force --clean 33 | # The GITHUB_TOKEN is automatically provided by GitHub Actions 34 | # and has the necessary permissions if `permissions: contents: write` is set for the job. 35 | -------------------------------------------------------------------------------- /.github/workflows/static-check.yml: -------------------------------------------------------------------------------- 1 | name: Code Quality Checks 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | code-quality: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout Charty Repository 17 | uses: actions/checkout@v3 18 | 19 | - name: Set up JDK 20 | uses: actions/setup-java@v3 21 | with: 22 | distribution: 'zulu' 23 | java-version: 17 24 | 25 | - name: Run Detekt 26 | run: ./gradlew detekt 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | /charty/build/* 17 | charty/build/* 18 | /.kotlin/* 19 | .kotlin/* 20 | /sample/build/* 21 | 22 | charty/src/androidMain/resources/* 23 | charty/src/androidMain/resources -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | chartyKMP -------------------------------------------------------------------------------- /.idea/AndroidProjectSystem.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/artifacts/sample_desktop.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/sample/build/libs 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/artifacts/sample_wasm_js.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/sample/build/libs 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 119 | 120 | 122 | 123 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/Charty.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetSelector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at hello2himanshusingh@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Charty 2 | 3 | Welcome to Charty! We appreciate your interest in contributing to this open-source project. By 4 | contributing, you can help improve the library, add new features, fix issues, and make Charty even 5 | better for the community. 6 | 7 | ## How Can You Contribute? 8 | 9 | - **Reporting Issues**: If you encounter any bugs or issues while using Charty, please let us know 10 | by creating a new issue in the [issue tracker](https://github.com/hi-manshu/Charty/issues) . 11 | Provide a detailed description, steps to reproduce, and any relevant information to help us 12 | investigate and address the problem. 13 | - **Feature Requests**: Have a great idea for a new feature or improvement? We'd love to hear it! 14 | Open a new issue in the [issue tracker](https://github.com/hi-manshu/Charty/issues) and clearly 15 | explain the proposed feature or enhancement. We'll review your suggestion and provide feedback. 16 | - **Pull Requests**: Want to contribute code to Charty? You can submit a pull request with your 17 | changes. Please follow the guidelines below: 18 | - Fork the repository and create a new branch for your changes. 19 | - Ensure your code adheres to the project's coding style and conventions. 20 | - Write clear, concise, and meaningful commit messages. 21 | - Include tests for your changes whenever applicable. Tests help ensure the stability and 22 | reliability of the library. 23 | - Update the documentation to reflect any changes or additions. 24 | - Submit the pull request, providing a detailed description of your changes and their purpose. 25 | - Documentation Improvements: You can help improve the Charty documentation by fixing typos, 26 | clarifying explanations, adding examples, or expanding on existing content. Submit a pull 27 | request with your documentation changes, ensuring they follow the same guidelines as code 28 | contributions. 29 | ## Code Style and Conventions 30 | 31 | To maintain consistency within the project, please adhere to the following guidelines: 32 | 33 | - Follow the existing code style and formatting conventions. 34 | - Use meaningful variable and function names that reflect their purpose. 35 | - Add comments to explain complex logic or provide context when necessary. 36 | - Write clear and concise code that is easy to understand and maintain. 37 | - Ensure your code is well-tested, following the existing testing patterns and conventions. 38 | 39 | ## Code of Conduct 40 | 41 | Contributors are expected to adhere to the Code of Conduct when participating in the Charty project. 42 | Be respectful, inclusive, and considerate of others. Any form of harassment, discrimination, or 43 | abusive behavior will not be tolerated. 44 | 45 | ## Getting Help 46 | 47 | If you need any assistance, have questions, or require further clarification, feel free to reach out 48 | by creating a new issue or contacting the project maintainers. 49 | 50 | Thank you for your contributions and support in making Charty a valuable tool for data visualization 51 | in the Android community! -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🎯Charty : Elementary Chart library for Compose with KMP support! 2 | 3 | ![Banner](img/banner.png) 4 | 5 | > A sleek & lightweight charting library for Jetpack Compose, now with **Kotlin Multiplatform (KMP)** support! 6 | > *Built with ❤️ by [@hi-manshu](https://github.com/hi-manshu) for developers who love charts.* 7 | 8 | _Made with ❤️ for Android Developers by Himanshu_ 9 | 10 | [![Github Followers](https://img.shields.io/github/followers/hi-manshu?label=Follow&style=social)](https://github.com/hi-manshu) 11 | [![Twitter Follow](https://img.shields.io/twitter/follow/hi_man_shoe?label=Follow&style=social)](https://twitter.com/hi_man_shoe) 12 | [![AndroidWeekly](https://img.shields.io/badge/Featured%20in%20androidweekly.net-%23532-orange)](https://androidweekly.net/issues/issue-532) 13 | ![GitHub issues](https://img.shields.io/github/issues/hi-manshu/charty) 14 | ![GitHub Repository size](https://img.shields.io/github/repo-size/hi-manshu/charty) 15 | ![GitHub forks](https://img.shields.io/github/forks/hi-manshu/charty) 16 | ![GitHub Repo stars](https://img.shields.io/github/stars/hi-manshu/charty) 17 | ![Charty](https://img.shields.io/maven-central/v/com.himanshoe/charty?color=f4c430&label=Maven%20Central%20%3A%20Charty) 18 | ![Charty Static Check](https://github.com/hi-manshu/charty/actions/workflows/static-check.yml/badge.svg) 19 | 20 | ## 📚 Documentation 21 | 22 | Find the full API reference and usage guide here: 23 | 👉 **[hi-manshu.github.io/charty](https://hi-manshu.github.io/charty/)** 24 | 25 | --- 26 | 27 | ## 🚀 Apps using Charty 28 | 29 | | App | Link | 30 | | --- | --- | 31 | | 🐱 **NEKO** | [github.com/nekomangaorg/Neko](https://github.com/nekomangaorg/Neko) | 32 | | ⏱️ **TimePlanner** | [github.com/v1tzor/TimePlanner](https://github.com/v1tzor/TimePlanner) | 33 | 34 | --- 35 | 36 | ## ⚖️ License 37 | 38 | ```text 39 | Copyright 2025 The Charty Authors 40 | 41 | Licensed under the Apache License, Version 2.0 (the "License"); 42 | you may not use this file except in compliance with the License. 43 | You may obtain a copy of the License at 44 | 45 | http://www.apache.org/licenses/LICENSE-2.0 46 | 47 | Unless required by applicable law or agreed to in writing, software 48 | distributed under the License is distributed on an "AS IS" BASIS, 49 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 | See the License for the specific language governing permissions and 51 | limitations under the License. 52 | ``` 53 | 54 | --- 55 | 56 | ## 🌟 Support 57 | 58 | If you like this library, consider giving it a ⭐ on [GitHub](https://github.com/hi-manshu/charty) — it helps a lot! 59 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | // trick: for the same plugin versions in all sub-modules 3 | alias(libs.plugins.androidLibrary).apply(false) 4 | alias(libs.plugins.kotlinMultiplatform).apply(false) 5 | alias(libs.plugins.androidApplication) apply false 6 | alias(libs.plugins.kotlinAndroid) apply false 7 | alias(libs.plugins.compose.compiler) apply false 8 | alias(libs.plugins.arturbosch.detekt) apply (false) 9 | alias(libs.plugins.composeMultiplatform) apply false 10 | } 11 | -------------------------------------------------------------------------------- /charty/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.SonatypeHost 2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget 3 | 4 | plugins { 5 | alias(libs.plugins.kotlinMultiplatform) 6 | alias(libs.plugins.androidLibrary) 7 | alias(libs.plugins.composeMultiplatform) 8 | alias(libs.plugins.compose.compiler) 9 | alias(libs.plugins.publish) 10 | alias(libs.plugins.dokka) 11 | } 12 | 13 | mavenPublishing { 14 | publishToMavenCentral(SonatypeHost.S01) 15 | signAllPublications() 16 | } 17 | 18 | kotlin { 19 | androidTarget { 20 | compilations.all { 21 | compileTaskProvider.configure { 22 | compilerOptions { 23 | jvmTarget.set(JvmTarget.JVM_1_8) 24 | } 25 | } 26 | } 27 | } 28 | 29 | listOf( 30 | iosX64(), 31 | iosArm64(), 32 | iosSimulatorArm64(), 33 | ).forEach { 34 | it.binaries.framework { 35 | baseName = "charty" 36 | isStatic = true 37 | } 38 | } 39 | 40 | sourceSets { 41 | commonMain.dependencies { 42 | implementation(compose.runtime) 43 | implementation(compose.ui) 44 | implementation(compose.runtime) 45 | implementation(compose.foundation) 46 | implementation(compose.material3) 47 | } 48 | commonTest.dependencies { 49 | implementation(libs.kotlin.test) 50 | } 51 | } 52 | } 53 | 54 | android { 55 | namespace = "com.himanshoe.charty" 56 | compileSdk = 35 57 | defaultConfig { 58 | minSdk = 24 59 | } 60 | compileOptions { 61 | sourceCompatibility = JavaVersion.VERSION_1_8 62 | targetCompatibility = JavaVersion.VERSION_1_8 63 | } 64 | } 65 | val detekt by configurations.creating 66 | dependencies { 67 | detekt(libs.detekt.cli) 68 | detekt(libs.detekt.formatting) 69 | debugImplementation(compose.uiTooling) 70 | dokkaPlugin(libs.dokka) 71 | } 72 | tasks.register("detekt") { 73 | mainClass = "io.gitlab.arturbosch.detekt.cli.Main" 74 | classpath = detekt 75 | 76 | val input = projectDir 77 | val config = "$projectDir/detekt.yml" 78 | val exclude = ".*/build/.*,.*/resources/.*" 79 | val report = "sarif:${layout.buildDirectory.file("reports/detekt/detekt.sarif").get()}" 80 | val params = listOf( 81 | "-i", 82 | input, 83 | "-c", 84 | config, 85 | "-ex", 86 | exclude, 87 | "-r", 88 | report, 89 | "--build-upon-default-config" 90 | ) 91 | 92 | args(params) 93 | } 94 | -------------------------------------------------------------------------------- /charty/detekt.yml: -------------------------------------------------------------------------------- 1 | complexity: 2 | LongParameterList: 3 | active: false 4 | TooManyFunctions: 5 | active: false 6 | LongMethod: 7 | threshold: 90 8 | ignoreAnnotated: [ "Composable" ] 9 | CyclomaticComplexMethod: 10 | ignoreAnnotated: [ "Composable" ] 11 | ComplexCondition: 12 | active: true 13 | threshold: 5 # Increase the threshold to allow more complex conditions 14 | 15 | naming: 16 | InvalidPackageDeclaration: 17 | rootPackage: "io.github.mrnuggelz.opensubsonic" 18 | TopLevelPropertyNaming: 19 | constantPattern: '[A-Z][_A-Za-z0-9]*' 20 | FunctionNaming: 21 | active: true 22 | functionPattern: '^[a-z][A-Za-z0-9]*$' 23 | ignoreAnnotated: [ "Composable" ] 24 | 25 | formatting: 26 | Indentation: 27 | active: false 28 | 29 | style: 30 | MaxLineLength: 31 | active: true 32 | maxLineLength: 166 33 | MagicNumber: 34 | active: false 35 | DestructuringDeclarationWithTooManyEntries: 36 | active: true 37 | maxDestructuringEntries: 6 # Increase the threshold to allow more complex conditions 38 | -------------------------------------------------------------------------------- /charty/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=charty 2 | POM_NAME=charty 3 | POM_DESCRIPTION=An Elementary Compose Multiplatform Chart library. 4 | POM_PACKAGING=aar 5 | POM_INCEPTION_YEAR=2025 6 | GROUP=com.himanshoe 7 | VERSION_NAME=2.1.0-beta03.4 8 | VERSION_CODE=3 9 | POM_URL=https://github.com/hi-manshu 10 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 11 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 12 | POM_LICENCE_DIST=repo 13 | POM_SCM_URL=https://github.com/hi-manshu 14 | POM_DEVELOPER_ID=hi-manshu 15 | POM_DEVELOPER_NAME=Himanshu Singh 16 | POM_DEVELOPER_URL=https://github.com/hi-manshu -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/SignalBarChart.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar 2 | 3 | import androidx.compose.animation.core.Animatable 4 | import androidx.compose.foundation.Canvas 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.runtime.LaunchedEffect 7 | import androidx.compose.runtime.remember 8 | import androidx.compose.ui.Modifier 9 | import androidx.compose.ui.geometry.CornerRadius 10 | import androidx.compose.ui.geometry.Offset 11 | import androidx.compose.ui.geometry.Size 12 | import androidx.compose.ui.graphics.Brush 13 | import androidx.compose.ui.graphics.Color 14 | import com.himanshoe.charty.common.ChartColor 15 | import com.himanshoe.charty.common.asSolidChartColor 16 | import kotlinx.coroutines.delay 17 | 18 | /** 19 | * A composable function that displays a signal bar chart with solid colors. 20 | * 21 | * @param progress A lambda function that returns the current progress as a Float. 22 | * @param modifier A Modifier to be applied to the Canvas. 23 | * @param trackColor The color to be used for the track. 24 | * @param progressColor The color to be used for the progress. 25 | * @param gapRatio A Float representing the ratio of the gap between blocks. 26 | */ 27 | @Composable 28 | fun SignalProgressBarChart( 29 | progress: () -> Float, 30 | maxProgress: Float = 100F, 31 | modifier: Modifier = Modifier, 32 | totalBlocks: Int = 10, 33 | trackColor: ChartColor = Color.Gray.asSolidChartColor(), 34 | progressColor: ChartColor = Color.Green.asSolidChartColor(), 35 | gapRatio: Float = 0.1F 36 | ) { 37 | SignalBarChartContent( 38 | progress = progress, 39 | totalBlocks = totalBlocks, 40 | trackColorBrush = Brush.linearGradient(trackColor.value), 41 | progressColorBrush = Brush.linearGradient(progressColor.value), 42 | gapRatio = gapRatio, 43 | maxProgress = maxProgress, 44 | modifier = modifier 45 | ) 46 | } 47 | 48 | @Composable 49 | fun SignalProgressBarChart( 50 | progress: () -> Int, 51 | maxProgress: Int, 52 | modifier: Modifier = Modifier, 53 | totalBlocks: Int = 10, 54 | trackColor: ChartColor = Color.Gray.asSolidChartColor(), 55 | progressColor: ChartColor = Color.Green.asSolidChartColor(), 56 | gapRatio: Float = 0.1F 57 | ) { 58 | SignalBarChartContent( 59 | progress = { progress.invoke().toFloat() }, 60 | totalBlocks = totalBlocks, 61 | trackColorBrush = Brush.linearGradient(trackColor.value), 62 | progressColorBrush = Brush.linearGradient(progressColor.value), 63 | gapRatio = gapRatio, 64 | maxProgress = maxProgress.toFloat(), 65 | modifier = modifier 66 | ) 67 | } 68 | 69 | /** 70 | * A private composable function that displays the content of a signal bar chart. 71 | * 72 | * @param progress A lambda function that returns the current progress as a Float. 73 | * @param trackColorBrush A Brush to be used for the track. 74 | * @param progressColorBrush A Brush to be used for the progress. 75 | * @param gapRatio A Float representing the ratio of the gap between blocks. 76 | * @param totalBlocks An Int representing the total number of blocks in the chart. 77 | * @param modifier A Modifier to be applied to the Canvas. 78 | */ 79 | @Composable 80 | private fun SignalBarChartContent( 81 | progress: () -> Float, 82 | maxProgress: Float, 83 | trackColorBrush: Brush, 84 | progressColorBrush: Brush, 85 | gapRatio: Float, 86 | totalBlocks: Int, 87 | modifier: Modifier = Modifier, 88 | ) { 89 | val alphaAnimation = remember { Animatable(0f) } 90 | LaunchedEffect(progress()) { 91 | delay(200) 92 | alphaAnimation.animateTo(progress()) 93 | } 94 | Canvas(modifier = modifier) { 95 | val filledBlocks = (alphaAnimation.value / maxProgress * totalBlocks).toInt() 96 | val partialBlockFraction = (alphaAnimation.value / maxProgress * totalBlocks) - filledBlocks 97 | val blockHeight = size.height / (totalBlocks + (totalBlocks - 1) * gapRatio) 98 | val gap = blockHeight * gapRatio 99 | val blockWidth = size.width 100 | 101 | for (index in 0 until totalBlocks) { 102 | val yOffset = size.height - (index + 1) * (blockHeight + gap) 103 | val topLeft = Offset(gap, yOffset) 104 | val blockSize = Size(blockWidth, blockHeight) 105 | val cornerRadius = CornerRadius(5F) 106 | when { 107 | index < filledBlocks -> { 108 | drawRoundRect( 109 | brush = progressColorBrush, 110 | topLeft = topLeft, 111 | size = blockSize, 112 | cornerRadius = cornerRadius, 113 | ) 114 | } 115 | 116 | index == filledBlocks -> { 117 | drawRoundRect( 118 | brush = progressColorBrush, 119 | cornerRadius = cornerRadius, 120 | topLeft = topLeft.copy(y = yOffset + blockHeight * (1 - partialBlockFraction)), 121 | size = blockSize.copy(height = blockHeight * partialBlockFraction) 122 | ) 123 | drawRoundRect( 124 | brush = trackColorBrush, 125 | cornerRadius = cornerRadius, 126 | topLeft = topLeft, 127 | size = blockSize.copy(height = blockHeight * (1 - partialBlockFraction)) 128 | ) 129 | } 130 | 131 | else -> { 132 | drawRoundRect( 133 | cornerRadius = cornerRadius, 134 | brush = trackColorBrush, 135 | topLeft = topLeft, 136 | size = blockSize 137 | ) 138 | } 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/StorageBar.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar 2 | 3 | import androidx.compose.foundation.Canvas 4 | import androidx.compose.foundation.gestures.detectTapGestures 5 | import androidx.compose.foundation.layout.fillMaxWidth 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.runtime.getValue 8 | import androidx.compose.runtime.mutableIntStateOf 9 | import androidx.compose.runtime.mutableStateOf 10 | import androidx.compose.runtime.setValue 11 | import androidx.compose.ui.Modifier 12 | import androidx.compose.ui.geometry.CornerRadius 13 | import androidx.compose.ui.geometry.Offset 14 | import androidx.compose.ui.geometry.Size 15 | import androidx.compose.ui.graphics.Brush 16 | import androidx.compose.ui.graphics.Color 17 | import androidx.compose.ui.graphics.Path 18 | import androidx.compose.ui.input.pointer.pointerInput 19 | import androidx.compose.ui.util.fastForEachIndexed 20 | import androidx.compose.ui.util.fastMap 21 | import com.himanshoe.charty.bar.model.StorageData 22 | import com.himanshoe.charty.common.ChartColor 23 | import com.himanshoe.charty.common.asSolidChartColor 24 | import com.himanshoe.charty.common.getDrawingPath 25 | 26 | /** 27 | * A composable function that displays a storage bar with a single track color. 28 | * 29 | * @param data A list of StorageData representing the categories and their values. 30 | * @param trackColor The color of the track. Default is a light gray color. 31 | * @param modifier The optional modifier to be applied to the StorageBar. 32 | * @param onClick A lambda function to be invoked when a category is clicked. 33 | */ 34 | @Composable 35 | fun StorageBar( 36 | data: () -> List, 37 | trackColor: ChartColor = Color(0xD3D3D3DE).asSolidChartColor(), 38 | modifier: Modifier = Modifier, 39 | onClick: (StorageData) -> Unit = {} 40 | ) { 41 | StorageBarContent( 42 | data = data, 43 | trackColorBrush = Brush.linearGradient(trackColor.value), 44 | modifier = modifier, 45 | onClick = onClick 46 | ) 47 | } 48 | 49 | @Composable 50 | private fun StorageBarContent( 51 | data: () -> List, 52 | trackColorBrush: Brush, 53 | modifier: Modifier = Modifier, 54 | onClick: (StorageData) -> Unit = {} 55 | ) { 56 | var clickedOffSet by mutableStateOf(null) 57 | var clickedBarIndex by mutableIntStateOf(-1) 58 | val storageData = data() 59 | Canvas( 60 | modifier = modifier 61 | .fillMaxWidth() 62 | .pointerInput(storageData) { 63 | detectTapGestures { offset -> clickedOffSet = offset } 64 | } 65 | ) { 66 | val totalWidth = size.width 67 | val totalHeight = size.height 68 | var currentOffset = 0f 69 | val categoryWidths = storageData.fastMap { it.value * totalWidth } 70 | 71 | storageData.fastForEachIndexed { index, category -> 72 | val categoryWidth = categoryWidths[index] 73 | val isFirst = index == 0 74 | val additionalHeight = if (clickedBarIndex == index) totalHeight * 0.05F else 0F 75 | val size = Size( 76 | width = categoryWidth, 77 | height = totalHeight + additionalHeight 78 | ) 79 | val path = calculatePath( 80 | offset = Offset(x = currentOffset, y = -additionalHeight / 2), 81 | size = size, 82 | isFirst = isFirst 83 | ) 84 | clickedOffSet?.x?.let { 85 | if (it in currentOffset..(currentOffset + categoryWidth)) { 86 | clickedBarIndex = index 87 | onClick(category) 88 | } 89 | } 90 | drawPath(path = path, brush = Brush.linearGradient(category.color.value)) 91 | currentOffset += categoryWidth 92 | } 93 | 94 | if (currentOffset < totalWidth) { 95 | val backgroundPath = calculatePath( 96 | offset = Offset(x = currentOffset, y = 0f), 97 | size = Size(width = totalWidth - currentOffset, height = totalHeight), 98 | isLast = true 99 | ) 100 | drawPath( 101 | path = backgroundPath, 102 | brush = trackColorBrush 103 | ) 104 | } 105 | } 106 | } 107 | 108 | private fun calculatePath( 109 | offset: Offset, 110 | size: Size, 111 | isFirst: Boolean = false, 112 | isLast: Boolean = false 113 | ): Path { 114 | val cornerRadius = CornerRadius(10F, 10F) 115 | return getDrawingPath( 116 | barTopLeft = offset, 117 | barRectSize = size, 118 | topLeftCornerRadius = if (isFirst) cornerRadius else CornerRadius.Zero, 119 | topRightCornerRadius = if (isLast) cornerRadius else CornerRadius.Zero, 120 | bottomLeftCornerRadius = if (isFirst) cornerRadius else CornerRadius.Zero, 121 | bottomRightCornerRadius = if (isLast) cornerRadius else CornerRadius.Zero, 122 | ) 123 | } 124 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/config/BarChartColorConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.config 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import com.himanshoe.charty.common.ChartColor 5 | import com.himanshoe.charty.common.asGradientChartColor 6 | 7 | /** 8 | * Configuration class for bar chart colors. 9 | * 10 | * @property fillBarColor The gradient colors for the bars. 11 | * @property negativeBarColors The gradient colors for negative bars. 12 | * @property barBackgroundColor The background color of the bars, defaults to a light gray color. 13 | * @property gridLineColor The color of the grid lines, defaults to a light gray color. 14 | * @property axisLineColor The color of the axis lines, defaults to a dark gray color. 15 | */ 16 | data class BarChartColorConfig( 17 | val fillBarColor: ChartColor, 18 | val negativeBarColors: ChartColor, 19 | val barBackgroundColor: ChartColor = ChartColor.Solid(Color(0x40D3D3D3)), 20 | val gridLineColor: ChartColor = ChartColor.Solid(Color(0xFFD3D3DE)), 21 | val axisLineColor: ChartColor = ChartColor.Solid(Color(0xFF444444)), 22 | ) { 23 | companion object { 24 | /** 25 | * Provides a default configuration for bar chart colors. 26 | * 27 | * @return A `BarChartColorConfig` object with default color settings. 28 | */ 29 | fun default() = 30 | BarChartColorConfig( 31 | fillBarColor = listOf( 32 | Color(0xFFD9A7C7), 33 | Color(0xFFFFFCDC), 34 | ).asGradientChartColor(), 35 | negativeBarColors = listOf( 36 | Color(0xFFCB356B), 37 | Color(0xFFBD3F32), 38 | ).asGradientChartColor() 39 | 40 | ) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/config/BarChartConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.config 2 | 3 | import androidx.compose.ui.geometry.CornerRadius 4 | 5 | /** 6 | * Configuration class for bar chart settings. 7 | * 8 | * @property showAxisLines A boolean indicating whether to show axis lines. 9 | * @property showGridLines A boolean indicating whether to show grid lines. 10 | * @property drawNegativeValueChart A boolean indicating whether to draw a chart with negative values. 11 | * @property showCurvedBar A boolean indicating whether to show bars with curved corners. 12 | * @property minimumBarCount The minimum number of bars to display in the chart. 13 | */ 14 | data class BarChartConfig( 15 | val showAxisLines: Boolean, 16 | val showGridLines: Boolean, 17 | val drawNegativeValueChart: Boolean, 18 | val showCurvedBar: Boolean, 19 | val minimumBarCount: Int, 20 | val cornerRadius: CornerRadius? 21 | ) { 22 | companion object { 23 | /** 24 | * Provides a default configuration for bar chart settings. 25 | * 26 | * @return A `BarChartConfig` object with default settings. 27 | */ 28 | fun default() = BarChartConfig( 29 | showAxisLines = true, 30 | showGridLines = true, 31 | drawNegativeValueChart = true, 32 | showCurvedBar = false, 33 | minimumBarCount = 7, 34 | cornerRadius = null 35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/config/BarTooltip.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.config 2 | 3 | sealed interface BarTooltip { 4 | 5 | data object BarTop : BarTooltip 6 | data object GraphTop : BarTooltip 7 | } 8 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/config/ComparisonBarChartConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.config 2 | 3 | /** 4 | * Configuration class for comparison bar chart settings. 5 | * 6 | * @property showAxisLines A boolean indicating whether to show axis lines. 7 | * @property showGridLines A boolean indicating whether to show grid lines. 8 | * @property drawNegativeValueChart A boolean indicating whether to draw a chart with negative values. 9 | * @property showCurvedBar A boolean indicating whether to show bars with curved corners. 10 | */ 11 | data class ComparisonBarChartConfig( 12 | val showAxisLines: Boolean, 13 | val showGridLines: Boolean, 14 | val drawNegativeValueChart: Boolean, 15 | val showCurvedBar: Boolean, 16 | ) { 17 | companion object { 18 | /** 19 | * Provides a default configuration for comparison bar chart settings. 20 | * 21 | * @return A `ComparisonBarChartConfig` object with default settings. 22 | */ 23 | fun default() = ComparisonBarChartConfig( 24 | showAxisLines = true, 25 | showGridLines = true, 26 | drawNegativeValueChart = true, 27 | showCurvedBar = false, 28 | ) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/config/HorizontalBarLabelConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.config 2 | 3 | import androidx.compose.ui.graphics.Brush 4 | import androidx.compose.ui.graphics.Color 5 | import androidx.compose.ui.text.TextStyle 6 | import androidx.compose.ui.unit.TextUnit 7 | import com.himanshoe.charty.common.ChartColor 8 | import com.himanshoe.charty.common.asGradientChartColor 9 | 10 | /** 11 | * Data class representing the configuration for horizontal bar labels. 12 | * 13 | * @property showLabel Indicates whether the label should be shown. 14 | * @property hasOverlappingLabel Indicates whether the label has overlapping. 15 | * @property textColor List of colors for the text. 16 | * @property textBackgroundColors List of background colors for the text. 17 | */ 18 | data class HorizontalBarLabelConfig( 19 | val showLabel: Boolean, 20 | val hasOverlappingLabel: Boolean, 21 | val textColor: ChartColor, 22 | val textBackgroundColors: ChartColor, 23 | val xAxisCharCount: Int?, 24 | val labelTextStyle: TextStyle?, 25 | ) { 26 | companion object { 27 | /** 28 | * Provides a default configuration for horizontal bar labels. 29 | * 30 | * @return A `HorizontalBarLabelConfig` object with default settings. 31 | */ 32 | fun default() = HorizontalBarLabelConfig( 33 | showLabel = false, 34 | hasOverlappingLabel = true, 35 | textColor = listOf( 36 | Color(0xffFFAFBD), 37 | Color(0xffffc3a0) 38 | ).asGradientChartColor(), 39 | xAxisCharCount = null, 40 | labelTextStyle = null, 41 | textBackgroundColors = listOf( 42 | Color(0xff0f0c29), 43 | Color(0xff302b63), 44 | Color(0xff24243e) 45 | ).asGradientChartColor(), 46 | ) 47 | } 48 | } 49 | 50 | internal fun HorizontalBarLabelConfig.getTetStyle( 51 | fontSize: TextUnit, 52 | ) = labelTextStyle ?: TextStyle( 53 | fontSize = fontSize, brush = Brush.linearGradient(textColor.value) 54 | ) 55 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/config/StackBarConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.config 2 | 3 | data class StackBarConfig( 4 | val showAxisLines: Boolean, 5 | val showGridLines: Boolean, 6 | val showCurvedBar: Boolean, 7 | val minimumBarCount: Int, 8 | ) { 9 | companion object { 10 | /** 11 | * Provides a default configuration for bar chart settings. 12 | * 13 | * @return A `StackBarConfig` object with default settings. 14 | */ 15 | fun default() = StackBarConfig( 16 | showAxisLines = true, 17 | showGridLines = true, 18 | showCurvedBar = false, 19 | minimumBarCount = 7, 20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/model/BarData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.model 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import com.himanshoe.charty.common.ChartColor 5 | import com.himanshoe.charty.common.asSolidChartColor 6 | 7 | /** 8 | * Data class representing a single bar in a bar chart. 9 | * 10 | * @property yValue The y-axis value of the bar. 11 | * @property xValue The x-axis value of the bar, can be of any type. 12 | * @property barColor The color of the bar, defaults to an unspecified color. 13 | * @property barBackgroundColor The background color of the bar, defaults to a light gray color. 14 | */ 15 | data class BarData( 16 | val yValue: Float, 17 | val xValue: Any, 18 | val barColor: ChartColor = Color.Unspecified.asSolidChartColor(), 19 | val barBackgroundColor: ChartColor = Color(0x40D3D3D3).asSolidChartColor(), 20 | ) 21 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/model/ComparisonBarData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.model 2 | 3 | import com.himanshoe.charty.common.ChartColor 4 | 5 | /** 6 | * Data class representing a comparison bar in a bar chart. 7 | * 8 | * @property label The label for the comparison bar. 9 | * @property bars A list of y-axis values for the bars. 10 | * @property colors A list of colors for the bars. 11 | * @constructor Creates a ComparisonBarData instance and ensures the size of bars and colors lists are equal. 12 | */ 13 | data class ComparisonBarData( 14 | val label: String, 15 | val bars: List, 16 | val colors: List 17 | ) { 18 | init { 19 | require(bars.size == colors.size) { 20 | "The size of the bars list must be equal to the size of the colors list." 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/model/StackBarData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.model 2 | 3 | import com.himanshoe.charty.common.ChartColor 4 | 5 | /** 6 | * Data class representing a comparison bar in a bar chart. 7 | * 8 | * @property label The label for the comparison bar. 9 | * @property values A list of y-axis values for the bars. 10 | * @property colors A list of colors for the bars. 11 | * @constructor Creates a ComparisonBarData instance and ensures the size of bars and colors lists are equal. 12 | */ 13 | data class StackBarData( 14 | val label: String, 15 | val values: List, 16 | val colors: List 17 | ) { 18 | init { 19 | require(values.size == colors.size) { 20 | "The size of the bars list must be equal to the size of the colors list." 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/bar/model/StorageData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.bar.model 2 | 3 | import com.himanshoe.charty.common.ChartColor 4 | 5 | /** 6 | * Data class representing storage data. 7 | * 8 | * @property name The name of the storage item. 9 | * @property value The value associated with the storage item. 10 | * @property color The color representing the storage item. 11 | */ 12 | data class StorageData( 13 | val name: String, 14 | val value: Float, 15 | val color: ChartColor 16 | ) 17 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/circle/CircleChart.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.circle 2 | 3 | import androidx.compose.foundation.Canvas 4 | import androidx.compose.foundation.gestures.detectTapGestures 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.runtime.getValue 7 | import androidx.compose.runtime.mutableStateOf 8 | import androidx.compose.runtime.remember 9 | import androidx.compose.runtime.setValue 10 | import androidx.compose.ui.Modifier 11 | import androidx.compose.ui.geometry.Offset 12 | import androidx.compose.ui.geometry.Size 13 | import androidx.compose.ui.graphics.Brush 14 | import androidx.compose.ui.graphics.Color 15 | import androidx.compose.ui.graphics.StrokeCap 16 | import androidx.compose.ui.graphics.drawscope.Stroke 17 | import androidx.compose.ui.input.pointer.pointerInput 18 | import androidx.compose.ui.util.fastForEachIndexed 19 | import androidx.compose.ui.util.fastMap 20 | import com.himanshoe.charty.circle.config.CircleChartConfig 21 | import com.himanshoe.charty.circle.model.CircleData 22 | import com.himanshoe.charty.circle.model.StartingPosition 23 | import kotlin.math.PI 24 | import kotlin.math.cos 25 | import kotlin.math.min 26 | import kotlin.math.sin 27 | 28 | /** 29 | * A composable function that displays a circle chart based on the provided data. 30 | * 31 | * @param data A lambda function that returns a list of CircleData objects representing the data to be displayed. 32 | * @param modifier A Modifier to be applied to the Canvas. 33 | * @param circleChartConfig Configuration for the circle chart, including whether to show the end indicator and the starting position. 34 | * @param onCircleClick A lambda function to handle click events on the circle. It receives the corresponding `CircleData` as parameters. 35 | */ 36 | @Composable 37 | fun CircleChart( 38 | data: () -> List, 39 | modifier: Modifier = Modifier, 40 | circleChartConfig: CircleChartConfig = CircleChartConfig.default(), 41 | onCircleClick: (CircleData) -> Unit = {} 42 | ) { 43 | CircleChartContent( 44 | modifier = modifier, 45 | onCircleClick = onCircleClick, 46 | data = data, 47 | showEndIndicator = circleChartConfig.showEndIndicator, 48 | startingPosition = circleChartConfig.startingPosition, 49 | ) 50 | } 51 | 52 | @Composable 53 | private fun CircleChartContent( 54 | data: () -> List, 55 | startingPosition: StartingPosition, 56 | modifier: Modifier = Modifier, 57 | showEndIndicator: Boolean = true, 58 | onCircleClick: (CircleData) -> Unit = {}, 59 | ) { 60 | var clickedCircleIndex by remember { mutableStateOf(-1) } 61 | val circleData = data() 62 | 63 | Canvas( 64 | modifier = modifier 65 | .pointerInput(Unit) { 66 | detectTapGestures { offset -> 67 | val maxRadius = min(size.width, size.height) / 2 68 | val center = Offset((size.width / 2).toFloat(), (size.height / 2).toFloat()) 69 | val radiusFactor = if (circleData.count() == 2) 1.55F else 1.45F 70 | val strokeWidth = maxRadius / (radiusFactor * circleData.size) 71 | val radiusStep = (maxRadius - strokeWidth) / circleData.size 72 | 73 | circleData.fastForEachIndexed { index, _ -> 74 | val currentRadius = maxRadius - (index * radiusStep) - strokeWidth 75 | val distance = (offset - center).getDistance() 76 | if (distance in (currentRadius - strokeWidth / 2)..(currentRadius + strokeWidth / 2)) { 77 | clickedCircleIndex = index 78 | } 79 | } 80 | } 81 | } 82 | ) { 83 | val maxRadius = min(size.width, size.height) / 2 84 | val center = Offset(size.width / 2, size.height / 2) 85 | val radiusFactor = if (circleData.count() == 2) 1.55F else 1.45F 86 | val strokeWidth = maxRadius / (radiusFactor * circleData.size) 87 | val radiusStep = (maxRadius - strokeWidth) / circleData.size 88 | 89 | circleData.fastForEachIndexed { index, item -> 90 | val currentRadius = maxRadius - (index * radiusStep) - strokeWidth 91 | val sweepAngle = 360 * (item.value / 100) 92 | val scaleFactor = if (index == clickedCircleIndex) 1.006F else 1.0F 93 | val scaledRadius = currentRadius * scaleFactor 94 | val scaledStrokeWidth = strokeWidth * scaleFactor 95 | 96 | // Draw the background circle 97 | drawCircle( 98 | brush = Brush.linearGradient( 99 | item.trackColor.value.fastMap { it.copy(alpha = 0.1F) } 100 | ), 101 | radius = scaledRadius, 102 | center = center, 103 | style = Stroke(width = scaledStrokeWidth) 104 | ) 105 | 106 | // Draw the foreground arc 107 | drawArc( 108 | brush = Brush.linearGradient(item.color.value), 109 | startAngle = startingPosition.angle, 110 | sweepAngle = sweepAngle, 111 | useCenter = false, 112 | topLeft = Offset(center.x - scaledRadius, center.y - scaledRadius), 113 | size = Size(scaledRadius * 2, scaledRadius * 2), 114 | style = Stroke(width = scaledStrokeWidth, cap = StrokeCap.Round) 115 | ) 116 | 117 | if (showEndIndicator) { 118 | // Draw the shadow at the end of the tip 119 | val endAngle = startingPosition.angle + sweepAngle 120 | val endX = center.x + scaledRadius * cos(endAngle.toRadians()) 121 | val endY = center.y + scaledRadius * sin(endAngle.toRadians()) 122 | drawCircle( 123 | center = Offset(endX, endY), 124 | radius = scaledStrokeWidth / 2, 125 | color = Color.Black.copy(alpha = 0.1f), 126 | ) 127 | } 128 | if (index == clickedCircleIndex) { 129 | onCircleClick(item) 130 | } 131 | } 132 | } 133 | } 134 | 135 | private fun Float.toRadians(): Float = (this * PI / 180).toFloat() 136 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/circle/config/CircleChartConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.circle.config 2 | 3 | import com.himanshoe.charty.circle.model.StartingPosition 4 | 5 | data class CircleChartConfig( 6 | val showEndIndicator: Boolean, 7 | val startingPosition: StartingPosition 8 | ) { 9 | companion object { 10 | fun default() = CircleChartConfig( 11 | showEndIndicator = true, 12 | startingPosition = StartingPosition.Bottom 13 | ) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/circle/config/DotConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.circle.config 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import com.himanshoe.charty.common.ChartColor 5 | import com.himanshoe.charty.common.asSolidChartColor 6 | 7 | /** 8 | * Configuration for the dots displayed along the arc in the speedometer progress bar. 9 | * 10 | * @param fillDotColor The color of the filled dots. 11 | * @param trackDotColor The color of the track dots. 12 | * @param count The number of dots to be displayed along the arc. 13 | * @param showDots A boolean indicating whether to show the dots or not. 14 | */ 15 | data class DotConfig( 16 | val fillDotColor: ChartColor, 17 | val trackDotColor: ChartColor, 18 | val count: Int = 50, 19 | val showDots: Boolean = true 20 | ) { 21 | companion object { 22 | /** 23 | * Returns the default configuration for the dots. 24 | * 25 | * @return A DotConfig object with default values. 26 | */ 27 | fun default() = DotConfig( 28 | fillDotColor = ChartColor.Gradient( 29 | listOf( 30 | Color(0xFFCB356B), 31 | Color(0xFFBD3F32), 32 | ) 33 | ), 34 | trackDotColor = Color.Gray.copy(alpha = 0.2F).asSolidChartColor() 35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/circle/model/CircleData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.circle.model 2 | 3 | import androidx.compose.ui.util.fastMap 4 | import com.himanshoe.charty.common.ChartColor 5 | import com.himanshoe.charty.common.asGradientChartColor 6 | 7 | /** 8 | * Data class representing a single slice of a circle chart. 9 | * 10 | * @property value The value of the pie chart slice. 11 | * @property color The color of the pie chart slice. 12 | * @property label The text label for the pie chart slice. 13 | */ 14 | data class CircleData( 15 | val value: Float, 16 | val color: ChartColor, 17 | val trackColor: ChartColor = color.value.fastMap { it.copy(alpha = 0.5F) }.asGradientChartColor(), 18 | val label: String, 19 | ) 20 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/circle/model/StartingPosition.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.circle.model 2 | 3 | sealed class StartingPosition(open val angle: Float) { 4 | data object Top : StartingPosition(angle = 270f) 5 | data object Bottom : StartingPosition(angle = 90f) 6 | data object Left : StartingPosition(angle = 180f) 7 | data object Right : StartingPosition(angle = 0f) 8 | data class Custom(override val angle: Float) : StartingPosition(angle) 9 | } 10 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/common/CanvasExt.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.common 2 | 3 | import androidx.compose.ui.geometry.CornerRadius 4 | import androidx.compose.ui.geometry.Offset 5 | import androidx.compose.ui.geometry.Rect 6 | import androidx.compose.ui.geometry.RoundRect 7 | import androidx.compose.ui.geometry.Size 8 | import androidx.compose.ui.graphics.Brush 9 | import androidx.compose.ui.graphics.Path 10 | import androidx.compose.ui.graphics.drawscope.DrawScope 11 | 12 | internal fun DrawScope.drawTargetLineIfNeeded( 13 | canvasWidth: Float, 14 | targetConfig: TargetConfig, 15 | yPoint: Float, 16 | ) { 17 | drawLine( 18 | brush = Brush.linearGradient(targetConfig.targetLineBarColors.value), 19 | start = Offset(0f, yPoint), 20 | end = Offset(canvasWidth, yPoint), 21 | pathEffect = targetConfig.pathEffect, 22 | strokeWidth = targetConfig.targetStrokeWidth 23 | ) 24 | } 25 | 26 | internal fun getDrawingPath( 27 | individualBarTopLeft: Offset, 28 | individualBarRectSize: Size, 29 | cornerRadius: CornerRadius 30 | ): Path { 31 | return Path().apply { 32 | addRoundRect( 33 | RoundRect( 34 | rect = Rect( 35 | offset = individualBarTopLeft, 36 | size = individualBarRectSize, 37 | ), 38 | topLeft = cornerRadius, 39 | topRight = cornerRadius, 40 | bottomLeft = CornerRadius.Zero, 41 | bottomRight = CornerRadius.Zero 42 | ) 43 | ) 44 | } 45 | } 46 | 47 | internal fun getDrawingPath( 48 | barTopLeft: Offset, 49 | barRectSize: Size, 50 | topLeftCornerRadius: CornerRadius, 51 | topRightCornerRadius: CornerRadius, 52 | bottomLeftCornerRadius: CornerRadius, 53 | bottomRightCornerRadius: CornerRadius, 54 | ): Path { 55 | return Path().apply { 56 | addRoundRect( 57 | RoundRect( 58 | rect = Rect( 59 | offset = barTopLeft, 60 | size = barRectSize, 61 | ), 62 | topLeft = topLeftCornerRadius, 63 | topRight = topRightCornerRadius, 64 | bottomLeft = bottomLeftCornerRadius, 65 | bottomRight = bottomRightCornerRadius 66 | ) 67 | ) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/common/ChartColor.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.common 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | /** 6 | * A sealed class representing different types of chart colors. 7 | * 8 | * @property value A list of colors used for the chart. 9 | */ 10 | sealed class ChartColor(open val value: List = emptyList()) { 11 | /** 12 | * A data class representing a solid color for the chart. 13 | * 14 | * @property color The solid color. 15 | */ 16 | data class Solid(val color: Color) : ChartColor(listOf(color, color)) 17 | 18 | /** 19 | * A data class representing a gradient color for the chart. 20 | * 21 | * @property value A list of colors used for the gradient. 22 | */ 23 | data class Gradient(override val value: List) : ChartColor(value) 24 | } 25 | 26 | /** 27 | * Extension function to convert a Color to a Solid ChartColor. 28 | * 29 | * @return A Solid ChartColor with the given color. 30 | */ 31 | fun Color.asSolidChartColor() = ChartColor.Solid(this) 32 | fun Color.asGradientChartColor() = ChartColor.Gradient(listOf(this, this)) 33 | 34 | /** 35 | * Extension function to convert a list of Colors to a Gradient ChartColor. 36 | * 37 | * @return A Gradient ChartColor with the given list of colors. 38 | */ 39 | fun List.asGradientChartColor() = ChartColor.Gradient(this) 40 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/common/LabelConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.common 2 | 3 | import androidx.compose.ui.graphics.Brush 4 | import androidx.compose.ui.graphics.Color 5 | import androidx.compose.ui.text.TextStyle 6 | import androidx.compose.ui.unit.TextUnit 7 | 8 | /** 9 | * Data class representing the configuration for labels in a chart. 10 | * 11 | * @property textColor The color of the text for the labels. 12 | * @property showXLabel A boolean indicating whether to show labels on the x-axis. 13 | * @property showYLabel A boolean indicating whether to show labels on the y-axis. 14 | */ 15 | data class LabelConfig( 16 | val textColor: ChartColor, 17 | val showXLabel: Boolean, 18 | val showYLabel: Boolean, 19 | val xAxisCharCount: Int?, 20 | val labelTextStyle: TextStyle?, 21 | ) { 22 | companion object { 23 | /** 24 | * Returns the default configuration for labels. 25 | * 26 | * @return A LabelConfig object with default settings. 27 | */ 28 | fun default() = LabelConfig( 29 | textColor = Color.Black.asSolidChartColor(), 30 | showXLabel = false, 31 | xAxisCharCount = null, 32 | labelTextStyle = null, 33 | showYLabel = false, 34 | ) 35 | } 36 | } 37 | 38 | internal fun LabelConfig.getXLabelTextCharCount( 39 | xValue: Any, 40 | displayDataCount: Int 41 | ) = xAxisCharCount ?: if (xValue.toString().length >= 3) { 42 | if (displayDataCount <= 7) 3 else 1 43 | } else { 44 | 1 45 | } 46 | 47 | internal fun LabelConfig.getTetStyle( 48 | fontSize: TextUnit, 49 | ) = labelTextStyle ?: TextStyle( 50 | fontSize = fontSize, 51 | brush = Brush.linearGradient(textColor.value) 52 | ) 53 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/common/TargetConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.common 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import androidx.compose.ui.graphics.PathEffect 5 | 6 | /** 7 | * Data class representing the configuration for the target line in a bar chart. 8 | * 9 | * @property targetLineBarColors A list of colors used for the gradient of the target line. 10 | * @property targetStrokeWidth The width of the target line. 11 | * @property pathEffect The path effect applied to the target line, such as dashes. 12 | */ 13 | data class TargetConfig( 14 | val targetLineBarColors: ChartColor, 15 | val targetStrokeWidth: Float, 16 | val pathEffect: PathEffect? 17 | ) { 18 | companion object { 19 | /** 20 | * Provides a default configuration for the target line. 21 | * 22 | * @return A `TargetConfig` object with default values. 23 | */ 24 | fun default() = TargetConfig( 25 | targetLineBarColors = ChartColor.Gradient( 26 | listOf( 27 | Color(0xFFffafbd), 28 | Color(0xFFffc3a0), 29 | ) 30 | ), 31 | targetStrokeWidth = 3F, 32 | pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f) 33 | ) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/common/TextConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.common 2 | 3 | import androidx.compose.ui.graphics.Brush 4 | import androidx.compose.ui.graphics.Color 5 | import androidx.compose.ui.text.TextStyle 6 | import androidx.compose.ui.unit.TextUnit 7 | import androidx.compose.ui.unit.sp 8 | 9 | data class TextConfig( 10 | val fontSize: TextUnit, 11 | val textColor: ChartColor, 12 | val style: TextStyle, 13 | val isVisible: Boolean 14 | ) { 15 | companion object { 16 | fun default( 17 | fontSize: TextUnit = 12.sp, 18 | color: ChartColor = Color.Gray.asSolidChartColor(), 19 | style: TextStyle = TextStyle(brush = Brush.linearGradient(color.value)) 20 | ) = TextConfig( 21 | fontSize = fontSize, 22 | textColor = color, 23 | style = style, 24 | isVisible = true 25 | ) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/line/config/LineChartColorConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.line.config 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import androidx.compose.ui.util.fastMap 5 | import com.himanshoe.charty.common.ChartColor 6 | 7 | /** 8 | * Data class representing the color configuration for a line chart. 9 | * 10 | * @property axisColor The color of the axis lines. 11 | * @property gridLineColor The color of the grid lines. 12 | * @property lineColor The color of the line in the chart. 13 | * @property lineFillColor The fill color under the line in the chart, with a default gradient based on the line color. 14 | * @property selectionBarColor The color of the selection bar. 15 | */ 16 | data class LineChartColorConfig( 17 | val axisColor: ChartColor, 18 | val gridLineColor: ChartColor, 19 | val lineColor: ChartColor, 20 | val lineFillColor: ChartColor = ChartColor.Gradient( 21 | lineColor.value.fastMap { 22 | it.copy(alpha = 0.2f) 23 | } 24 | ), 25 | val selectionBarColor: ChartColor 26 | ) { 27 | companion object { 28 | /** 29 | * Returns the default configuration for the line chart colors. 30 | * 31 | * @return A LineChartColorConfig object with default color settings. 32 | */ 33 | fun default() = LineChartColorConfig( 34 | axisColor = ChartColor.Gradient(listOf(Color.Gray, Color.Gray)), 35 | gridLineColor = ChartColor.Gradient(listOf(Color.Gray, Color.Gray)), 36 | lineColor = ChartColor.Gradient( 37 | listOf( 38 | Color(0xFFCB356B), 39 | Color(0xFFBD3F32), 40 | ) 41 | ), 42 | selectionBarColor = ChartColor.Gradient( 43 | listOf( 44 | Color.White.copy(alpha = 0.3f), 45 | Color.Gray.copy(alpha = 0.2f), 46 | ) 47 | ), 48 | lineFillColor = ChartColor.Gradient( 49 | listOf( 50 | Color(0xFFFFFFFF).copy(alpha = 0.3f), 51 | Color(0xFFff6a00).copy(alpha = 0.3f) 52 | ) 53 | ) 54 | ) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/line/config/LineChartConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.line.config 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import androidx.compose.ui.graphics.PathEffect 5 | import androidx.compose.ui.graphics.StrokeCap 6 | import androidx.compose.ui.text.TextStyle 7 | import com.himanshoe.charty.common.ChartColor 8 | 9 | /** 10 | * Configuration for the line chart. 11 | * 12 | * @property axisConfig Configuration for the chart axis. 13 | * @property gridConfig Configuration for the chart grid. 14 | * @property lineConfig Configuration for the line in the chart. 15 | * @property interactionTooltipConfig Configuration for the interaction tooltip. 16 | */ 17 | data class LineChartConfig( 18 | val axisConfig: LineChartAxisConfig = LineChartAxisConfig(), 19 | val gridConfig: LineChartGridConfig = LineChartGridConfig(), 20 | val lineConfig: LineConfig = LineConfig(), 21 | val interactionTooltipConfig: InteractionTooltipConfig = InteractionTooltipConfig() 22 | ) 23 | 24 | /** 25 | * Configuration for the chart axis. 26 | * 27 | * @property axisLineWidth Width of the axis lines. 28 | */ 29 | data class LineChartAxisConfig( 30 | val axisLineWidth: Float = 2f 31 | ) 32 | 33 | /** 34 | * Configuration for the chart grid. 35 | * 36 | * @property gridLineWidth Width of the grid lines. 37 | * @property gridLinePathEffect Path effect for the grid lines. 38 | */ 39 | data class LineChartGridConfig( 40 | val gridLineWidth: Float = 1f, 41 | val gridLinePathEffect: PathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f) 42 | ) 43 | 44 | /** 45 | * Configuration for the line in the chart. 46 | * 47 | * @property lineChartStrokeWidth Stroke width of the line. 48 | * @property lineCap Stroke cap style of the line. 49 | * @property drawPointerCircle Whether to draw a pointer circle on the line. 50 | * @property showValueOnLine Whether to show values on the line. 51 | * @property valueTextStyle Text style for the values on the line. 52 | * @property valueTextColor Text color for the values on the line. 53 | */ 54 | data class LineConfig( 55 | val lineChartStrokeWidth: Float = 5f, 56 | val lineCap: StrokeCap = StrokeCap.Round, 57 | val drawPointerCircle: Boolean = false, 58 | val showValueOnLine: Boolean = false, 59 | val valueTextStyle: TextStyle? = null, 60 | val valueTextColor: ChartColor = ChartColor.Solid(Color.Black), 61 | ) 62 | 63 | /** 64 | * Configuration for the interaction tooltip. 65 | * 66 | * @property isLongPressDragEnabled Whether long press drag is enabled. 67 | * @property textStyle Text style for the tooltip text. 68 | * @property textColor Text color for the tooltip text. 69 | * @property containerColor Background color for the tooltip container. 70 | * @property indicatorLineWidth Width of the indicator line. 71 | * @property indicatorLineColor Color of the indicator line. 72 | * @property indicatorLinePathEffect Path effect for the indicator line. 73 | */ 74 | data class InteractionTooltipConfig( 75 | val isLongPressDragEnabled: Boolean = false, 76 | val textStyle: TextStyle? = null, 77 | val textColor: ChartColor = ChartColor.Solid(Color.White), 78 | val containerColor: ChartColor = ChartColor.Gradient( 79 | listOf( 80 | Color(0xFFCB356B), 81 | Color(0xFFBD3F32) 82 | ) 83 | ), 84 | val indicatorLineWidth: Float = 5f, 85 | val indicatorLineColor: ChartColor = ChartColor.Gradient( 86 | listOf( 87 | Color(0xFFFFFFFF), 88 | Color(0xFFff6a00) 89 | ) 90 | ), 91 | val indicatorLinePathEffect: PathEffect? = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f) 92 | ) 93 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/line/ext/ModifierExt.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.line.ext 2 | 3 | import androidx.compose.ui.Modifier 4 | import androidx.compose.ui.draw.drawBehind 5 | import androidx.compose.ui.geometry.Offset 6 | import androidx.compose.ui.graphics.Brush 7 | import androidx.compose.ui.text.TextMeasurer 8 | import androidx.compose.ui.text.TextStyle 9 | import androidx.compose.ui.text.drawText 10 | import androidx.compose.ui.unit.dp 11 | import androidx.compose.ui.unit.sp 12 | import androidx.compose.ui.util.fastForEachIndexed 13 | import com.himanshoe.charty.common.LabelConfig 14 | import com.himanshoe.charty.common.getTetStyle 15 | import com.himanshoe.charty.common.getXLabelTextCharCount 16 | import com.himanshoe.charty.line.config.LineChartColorConfig 17 | import com.himanshoe.charty.line.config.LineChartConfig 18 | import com.himanshoe.charty.line.model.LineData 19 | 20 | /** 21 | * Extension function to draw axes and grid lines on a line chart. 22 | * 23 | * @receiver Modifier The modifier to which this function is applied. 24 | * @param data A list of LineData objects representing the data points for the chart. 25 | * @param colorConfig The color configuration for the chart. 26 | * @param chartConfig The configuration for the chart, including line widths and path effects. 27 | * @param textMeasurer The TextMeasurer used to measure and draw text. 28 | * @param labelConfig The configuration for the labels, including whether to show labels on the axes. 29 | * @param minValue The minimum value on the y-axis. 30 | * @param yRange The range of values on the y-axis. 31 | * @return A Modifier with the axes and grid lines drawn. 32 | */ 33 | internal fun Modifier.drawAxesAndGridLines( 34 | data: List, 35 | colorConfig: LineChartColorConfig, 36 | chartConfig: LineChartConfig, 37 | textMeasurer: TextMeasurer, 38 | labelConfig: LabelConfig, 39 | minValue: Float, 40 | yRange: Float, 41 | ) = this.drawBehind { 42 | val canvasWidth = size.width 43 | val canvasHeight = size.height 44 | val xStep = canvasWidth / (data.size - 1) 45 | val yStep = canvasHeight / 4 46 | 47 | // Draw X and Y axis 48 | drawLine( 49 | brush = Brush.linearGradient(colorConfig.axisColor.value), 50 | start = Offset(0f, canvasHeight), 51 | end = Offset(canvasWidth, canvasHeight), 52 | strokeWidth = chartConfig.axisConfig.axisLineWidth 53 | ) 54 | drawLine( 55 | brush = Brush.linearGradient(colorConfig.axisColor.value), 56 | start = Offset(0f, 0f), 57 | end = Offset(0f, canvasHeight), 58 | strokeWidth = chartConfig.axisConfig.axisLineWidth 59 | ) 60 | 61 | // Draw parallel lines to X axis 62 | for (i in 1..4) { 63 | val yOffset = canvasHeight - i * yStep 64 | drawLine( 65 | brush = Brush.linearGradient(colorConfig.gridLineColor.value), 66 | start = Offset(0f, yOffset), 67 | pathEffect = chartConfig.gridConfig.gridLinePathEffect, 68 | end = Offset(canvasWidth, yOffset), 69 | strokeWidth = chartConfig.gridConfig.gridLineWidth 70 | ) 71 | } 72 | // Draw labels 73 | if (labelConfig.showXLabel) { 74 | data.fastForEachIndexed { index, lineData -> 75 | val textCharCount = labelConfig.getXLabelTextCharCount( 76 | xValue = lineData.xValue, 77 | displayDataCount = data.count() 78 | ) 79 | val textSizeFactor = if (data.count() <= 13) 70 else 90 80 | 81 | val textLayoutResult = textMeasurer.measure( 82 | text = lineData.xValue.toString().take(textCharCount), 83 | style = TextStyle(fontSize = (canvasWidth / textSizeFactor).sp), 84 | ) 85 | 86 | drawText( 87 | textLayoutResult = textLayoutResult, 88 | topLeft = Offset( 89 | x = index * xStep - textLayoutResult.size.width / 2, 90 | y = canvasHeight + 4.dp.toPx() // Position below the X-axis 91 | ), 92 | brush = Brush.linearGradient(labelConfig.textColor.value) 93 | ) 94 | } 95 | } 96 | 97 | if (labelConfig.showYLabel) { 98 | for (i in 0..4) { 99 | val value = minValue + i * yRange / 4 100 | val textLayoutResult = textMeasurer.measure( 101 | text = value.toString(), 102 | style = labelConfig.getTetStyle(fontSize = (canvasWidth / 70).sp), 103 | ) 104 | drawText( 105 | textLayoutResult = textLayoutResult, 106 | topLeft = Offset( 107 | x = -textLayoutResult.size.width - 8f, 108 | y = canvasHeight - i * yStep - textLayoutResult.size.height / 2 109 | ), 110 | brush = Brush.linearGradient(labelConfig.textColor.value) 111 | ) 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/line/model/LineData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.line.model 2 | 3 | /** 4 | * Data class representing a data point in a line chart. 5 | * 6 | * @property yValue The y-axis value of the data point. 7 | * @property xValue The x-axis value of the data point, which can be of any type. 8 | */ 9 | data class LineData( 10 | val yValue: Float, 11 | val xValue: Any, 12 | ) 13 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/line/model/MultiLineData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.line.model 2 | 3 | import com.himanshoe.charty.line.config.LineChartColorConfig 4 | 5 | /** 6 | * Data class representing multiple lines of data in a line chart. 7 | * 8 | * @property data A list of LineData objects representing the data points for the lines. 9 | * @property colorConfig The color configuration for the lines in the chart. 10 | */ 11 | data class MultiLineData( 12 | val data: List, 13 | val colorConfig: LineChartColorConfig 14 | ) 15 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/pie/model/PieChartData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.pie.model 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import com.himanshoe.charty.common.ChartColor 5 | import com.himanshoe.charty.common.asSolidChartColor 6 | 7 | /** 8 | * Data class representing a single slice of a pie chart. 9 | * 10 | * @property value The value of the pie chart slice. 11 | * @property color The color of the pie chart slice. 12 | * @property labelColor The color of the label text for the pie chart slice. Defaults to white. 13 | * @property label The text label for the pie chart slice. 14 | */ 15 | data class PieChartData( 16 | val value: Float, 17 | val color: ChartColor, 18 | val labelColor: ChartColor = Color.White.asSolidChartColor(), 19 | val label: String, 20 | ) 21 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/point/model/PointChartColorConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.point.model 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import androidx.compose.ui.util.fastMap 5 | import com.himanshoe.charty.common.ChartColor 6 | 7 | /** 8 | * Data class representing the color configuration for a point chart. 9 | * 10 | * @property axisColor The color of the axis lines. 11 | * @property gridLineColor The color of the grid lines. 12 | * @property circleColor The color of the circles in the chart. 13 | * @property strokeColor The stroke color of the circles, with a default gradient based on the circle color. 14 | * @property selectionBarColor The color of the selection bar. 15 | */ 16 | data class PointChartColorConfig( 17 | val axisColor: ChartColor, 18 | val gridLineColor: ChartColor, 19 | val circleColor: ChartColor, 20 | val strokeColor: ChartColor = ChartColor.Gradient( 21 | circleColor.value.fastMap { 22 | it.copy(alpha = 0.5f) 23 | } 24 | ), 25 | val selectionBarColor: ChartColor 26 | ) { 27 | companion object { 28 | /** 29 | * Returns the default configuration for the point chart colors. 30 | * 31 | * @return A PointChartColorConfig object with default color settings. 32 | */ 33 | fun default() = PointChartColorConfig( 34 | axisColor = ChartColor.Gradient(listOf(Color.Gray, Color.Gray)), 35 | gridLineColor = ChartColor.Gradient(listOf(Color.Gray, Color.Gray)), 36 | circleColor = ChartColor.Gradient( 37 | listOf( 38 | Color(0xFFCB356B), 39 | Color(0xFFBD3F32), 40 | ) 41 | ), 42 | selectionBarColor = ChartColor.Gradient( 43 | listOf( 44 | Color.White.copy(alpha = 0.3f), 45 | Color.Gray.copy(alpha = 0.2f), 46 | ) 47 | ), 48 | strokeColor = ChartColor.Gradient( 49 | listOf( 50 | Color(0xFFFFFFFF).copy(alpha = 0.3f), 51 | Color(0xFFff6a00).copy(alpha = 0.3f) 52 | ) 53 | ) 54 | ) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/point/model/PointChartConfig.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.point.model 2 | 3 | import androidx.compose.animation.core.Easing 4 | import androidx.compose.animation.core.LinearEasing 5 | import androidx.compose.ui.graphics.PathEffect 6 | 7 | /** 8 | * Data class representing the configuration for a point chart. 9 | * 10 | * @property axisLineWidth The width of the axis lines. 11 | * @property gridLineWidth The width of the grid lines. 12 | * @property circleRadius The radius of the circles in the chart. 13 | * @property showClickedBar A boolean indicating whether to show a bar when a point is clicked. 14 | * @property animationDurationMillis The duration of the animation in milliseconds. 15 | * @property animationEasing The easing function for the animation. 16 | * @property animatePoints A boolean indicating whether to animate the points. 17 | * @property gridLinePathEffect The path effect for the grid lines. 18 | */ 19 | data class PointChartConfig( 20 | val axisLineWidth: Float = 2f, 21 | val gridLineWidth: Float = 1f, 22 | val circleRadius: Float = 10f, 23 | val showClickedBar: Boolean = true, 24 | val animationDurationMillis: Int = 500, 25 | val animationEasing: Easing = LinearEasing, 26 | val animatePoints: Boolean = true, 27 | val gridLinePathEffect: PathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f), 28 | ) 29 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/point/model/PointData.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.point.model 2 | 3 | /** 4 | * Data class representing a data point in a point chart. 5 | * 6 | * @property yValue The y-axis value of the data point. 7 | * @property xValue The x-axis value of the data point, which can be of any type. 8 | */ 9 | data class PointData( 10 | val yValue: Float, 11 | val xValue: Any, 12 | ) 13 | -------------------------------------------------------------------------------- /charty/src/commonMain/kotlin/com/himanshoe/charty/point/modifier/ModifierExt.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.charty.point.modifier 2 | 3 | import androidx.compose.ui.Modifier 4 | import androidx.compose.ui.draw.drawBehind 5 | import androidx.compose.ui.geometry.Offset 6 | import androidx.compose.ui.graphics.Brush 7 | import androidx.compose.ui.text.TextMeasurer 8 | import androidx.compose.ui.text.drawText 9 | import androidx.compose.ui.unit.dp 10 | import androidx.compose.ui.unit.sp 11 | import androidx.compose.ui.util.fastForEachIndexed 12 | import com.himanshoe.charty.common.LabelConfig 13 | import com.himanshoe.charty.common.getTetStyle 14 | import com.himanshoe.charty.common.getXLabelTextCharCount 15 | import com.himanshoe.charty.point.model.PointChartColorConfig 16 | import com.himanshoe.charty.point.model.PointChartConfig 17 | import com.himanshoe.charty.point.model.PointData 18 | 19 | /** 20 | * Extension function to draw axes and grid lines on a point chart. 21 | * 22 | * @receiver Modifier The modifier to which this function is applied. 23 | * @param data A list of PointData objects representing the data points for the chart. 24 | * @param colorConfig The color configuration for the chart. 25 | * @param chartConfig The configuration for the chart, including line widths and path effects. 26 | * @param textMeasurer The TextMeasurer used to measure and draw text. 27 | * @param labelConfig The configuration for the labels, including whether to show labels on the axes. 28 | * @param minValue The minimum value on the y-axis. 29 | * @param yRange The range of values on the y-axis. 30 | * @return A Modifier with the axes and grid lines drawn. 31 | */ 32 | internal fun Modifier.drawAxesAndGridLines( 33 | data: List, 34 | colorConfig: PointChartColorConfig, 35 | chartConfig: PointChartConfig, 36 | textMeasurer: TextMeasurer, 37 | labelConfig: LabelConfig, 38 | minValue: Float, 39 | yRange: Float, 40 | ) = this.drawBehind { 41 | val canvasWidth = size.width 42 | val canvasHeight = size.height 43 | val xStep = canvasWidth / data.size 44 | val yStep = canvasHeight / 4 45 | 46 | // Draw X and Y axis 47 | drawLine( 48 | brush = Brush.linearGradient(colorConfig.axisColor.value), 49 | start = Offset(0f, canvasHeight), 50 | end = Offset(canvasWidth, canvasHeight), 51 | strokeWidth = chartConfig.axisLineWidth 52 | ) 53 | drawLine( 54 | brush = Brush.linearGradient(colorConfig.axisColor.value), 55 | start = Offset(0f, 0f), 56 | end = Offset(0f, canvasHeight), 57 | strokeWidth = chartConfig.axisLineWidth 58 | ) 59 | 60 | // Draw parallel lines to X axis 61 | for (i in 1..4) { 62 | val yOffset = canvasHeight - i * yStep 63 | drawLine( 64 | brush = Brush.linearGradient(colorConfig.gridLineColor.value), 65 | start = Offset(0f, yOffset), 66 | pathEffect = chartConfig.gridLinePathEffect, 67 | end = Offset(canvasWidth, yOffset), 68 | strokeWidth = chartConfig.gridLineWidth 69 | ) 70 | } 71 | // Draw labels 72 | if (labelConfig.showXLabel) { 73 | data.fastForEachIndexed { index, circleData -> 74 | val textCharCount = labelConfig.getXLabelTextCharCount(circleData.xValue, data.count()) 75 | val textSizeFactor = if (data.count() <= 13) 70 else 90 76 | 77 | val textLayoutResult = textMeasurer.measure( 78 | text = circleData.xValue.toString().take(textCharCount), 79 | style = labelConfig.getTetStyle(fontSize = (canvasWidth / textSizeFactor).sp), 80 | ) 81 | drawText( 82 | textLayoutResult = textLayoutResult, 83 | topLeft = Offset( 84 | x = (index + 0.5f) * xStep - textLayoutResult.size.width / 2, 85 | y = canvasHeight + 4.dp.toPx() 86 | ), 87 | brush = Brush.linearGradient(labelConfig.textColor.value) 88 | ) 89 | } 90 | } 91 | 92 | if (labelConfig.showYLabel) { 93 | for (i in 0..4) { 94 | val value = if (minValue >= 0) i * yRange / 4 else minValue + i * yRange / 4 95 | val textLayoutResult = textMeasurer.measure( 96 | text = value.toString(), 97 | style = labelConfig.getTetStyle(fontSize = (canvasWidth / 70).sp), 98 | ) 99 | drawText( 100 | textLayoutResult = textLayoutResult, 101 | topLeft = Offset( 102 | x = -textLayoutResult.size.width - 8f, 103 | y = canvasHeight - i * yStep - textLayoutResult.size.height / 2 104 | ), 105 | brush = Brush.linearGradient(labelConfig.textColor.value) 106 | ) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /docs/charts/bar_chart.md: -------------------------------------------------------------------------------- 1 | # Bar Chart 2 | 3 | ![barchart_01.png](../site/img/bar/barchart_01.png) 4 | 5 | ## 🍸Overview 6 | A highly customizable and interactive bar chart Composable designed for displaying a list of bars with optional target indicators, tooltips, and click interactions. This component is flexible enough to be used in dashboards, analytical tools, or any visual data representation context in a Jetpack Compose application. 7 | 8 | ## 📦 Package 9 | 10 | ```kotlin 11 | import com.himanshoe.charty.bar 12 | ``` 13 | 14 | ## 🧱 Declaration 15 | 16 | ```kotlin 17 | @Composable 18 | fun BarChart( 19 | data: () -> List, 20 | modifier: Modifier = Modifier, 21 | target: Float? = null, 22 | targetConfig: TargetConfig = TargetConfig.default(), 23 | barChartConfig: BarChartConfig = BarChartConfig.default(), 24 | labelConfig: LabelConfig = LabelConfig.default(), 25 | barTooltip: BarTooltip? = null, 26 | barChartColorConfig: BarChartColorConfig = BarChartColorConfig.default(), 27 | onBarClick: (Int, BarData) -> Unit = { _, _ -> }, 28 | ) 29 | ``` 30 | 31 | ## 🔧 Parameters 32 | | Parameter | Type | Description | 33 | |-----------------------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| 34 | | `data` | `() -> List` | A lambda returning the list of `BarData` entries to be displayed in the chart. The list determines the number and height of bars. | 35 | | `modifier` | `Modifier` | Optional Compose `Modifier` for layout behavior, styling, padding, etc. | 36 | | `target` | `Float?` | Optional float value indicating a target or benchmark line to be displayed across the chart. If `null`, no target line is shown. | 37 | | `targetConfig` | `TargetConfig` | Configuration for the appearance of the target line, such as color, stroke, and label visibility. Use `TargetConfig.default()` for default styling. | 38 | | `barChartConfig` | `BarChartConfig` | Governs bar spacing, corner radius, chart padding, and other display properties. Customize using `BarChartConfig`. | 39 | | `labelConfig` | `LabelConfig` | Controls how labels for each bar are rendered (font size, visibility, position, etc.). | 40 | | `barTooltip` | `BarTooltip?` | Optional tooltip configuration shown on long-press or hover over a bar. Set to `null` to disable tooltips. | 41 | | `barChartColorConfig` | `BarChartColorConfig` | Specifies the color scheme for bars, labels, backgrounds, and the target line. Use `BarChartColorConfig.default()` for standard colors. | 42 | | `onBarClick` | `(Int, BarData) -> Unit` | Lambda called when a bar is clicked. Provides the index of the bar and the corresponding `BarData`. Default is a no-op. | 43 | 44 | 45 | ## 🧮 BarData Model 46 | | Property | Type | Description | 47 | |----------------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 48 | | `yValue` | `Float` | The numeric value to be plotted on the **y-axis**. This determines the height of the bar. | 49 | | `xValue` | `Any` | The corresponding value for the **x-axis**. It can represent a label, date, or category and can be of any type. | 50 | | `barColor` | `ChartColor` | The fill color of the bar. Defaults to `Color.Unspecified` converted to `SolidChartColor`. | 51 | | `barBackgroundColor` | `ChartColor` | The background color behind the filled portion of the bar, typically used to indicate the max range or to add contrast. Defaults to a semi-transparent light gray (`#40D3D3D3`). | 52 | 53 | 54 | > You can find a mock implementation in sample module's App file 55 | 56 | ## Example Usage 57 | 58 | ```kotlin 59 | private fun LazyListScope.addBarChart(target: Float?, data: List) { 60 | item { 61 | BarChart( 62 | modifier = Modifier.padding(10.dp).fillMaxWidth().height(300.dp), 63 | target = target, 64 | barTooltip = BarTooltip.GraphTop, 65 | labelConfig = LabelConfig.default().copy( 66 | showXLabel = true, 67 | xAxisCharCount = 4, 68 | showYLabel = true, 69 | textColor = Color.Black.asSolidChartColor() 70 | ), 71 | barChartColorConfig = BarChartColorConfig.default().copy( 72 | fillBarColor = Color(0xFFFF92C1).asSolidChartColor(), 73 | negativeBarColors = Color(0xFF4D4D4D).asSolidChartColor() 74 | ), 75 | data = { data }, 76 | barChartConfig = BarChartConfig.default().copy( 77 | cornerRadius = CornerRadius(40F, 40F), 78 | ), 79 | onBarClick = { index, barData -> println("click in bar with $index index and data $barData") } 80 | ) 81 | } 82 | } 83 | ``` -------------------------------------------------------------------------------- /docs/charts/circle_chart.md: -------------------------------------------------------------------------------- 1 | # Circle Chart 2 | 3 | ![circleChart_01.png](../site/img/circle/circleChart_01.png) 4 | 5 | ## 🍸Overview 6 | A customizable and interactive circle chart (like Apple tracking) used for visualizing proportions or segments of a dataset. 7 | 8 | ## 📦 Package 9 | 10 | ```kotlin 11 | import com.himanshoe.charty.circle 12 | ``` 13 | 14 | ## 🧱 Declaration 15 | 16 | ```kotlin 17 | @Composable 18 | fun CircleChart( 19 | data: () -> List, 20 | modifier: Modifier = Modifier, 21 | circleChartConfig: CircleChartConfig = CircleChartConfig.default(), 22 | onCircleClick: (CircleData) -> Unit = {} 23 | ) 24 | ``` 25 | 26 | ## 🔧 Parameters 27 | | Parameter | Type | Description | 28 | |---------------------|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| 29 | | `data` | `() -> List` | A lambda returning the list of `CircleData` objects to be displayed in the chart. Each data entry defines a segment's value and appearance. | 30 | | `modifier` | `Modifier` | Optional Compose `Modifier` to customize layout, size, padding, alignment, etc. | 31 | | `circleChartConfig` | `CircleChartConfig` | Chart appearance and layout configuration (e.g. stroke width, spacing, animation, inner radius). Defaults to `CircleChartConfig.default()`. | 32 | | `onCircleClick` | `(CircleData) -> Unit` | Lambda that is invoked when a segment of the chart is clicked. Provides the corresponding `CircleData` item. Default is a no-op. | 33 | 34 | 35 | ## 🧮 CircleData Model 36 | 37 | ```kotlin 38 | data class CircleData( 39 | val value: Float, 40 | val color: ChartColor, 41 | val trackColor: ChartColor = color.value.fastMap { it.copy(alpha = 0.5F) }.asGradientChartColor(), 42 | val label: String, 43 | ) 44 | ``` 45 | | Property | Type | Description | 46 | |--------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 47 | | `value` | `Float` | The numeric value representing the size of the slice. This value is used to calculate the angle of the slice relative to the sum of all values. | 48 | | `color` | `ChartColor` | The main color used to fill the slice. Should be visually distinct for each segment. | 49 | | `trackColor` | `ChartColor` | A secondary, typically lighter or semi-transparent version of the main color. It can be used for rendering background rings, shadows, or hover states. Defaults to a gradient based on the main color with reduced alpha (50%). | 50 | | `label` | `String` | The label or description of the slice. Useful for legends or tooltips. | 51 | 52 | 53 | > You can find a mock implementation in sample module's App file 54 | 55 | ## Example Usage 56 | 57 | ```kotlin 58 | val chartItems = listOf( 59 | CircleData(value = 40f, label = "Food", color = Color.Red.asSolidChartColor()), 60 | CircleData(value = 30f, label = "Transport", color = Color.Blue.asSolidChartColor()), 61 | CircleData(value = 30f, label = "Others", color = Color.Green.asSolidChartColor()) 62 | ) 63 | 64 | CircleChart( 65 | data = { chartItems }, 66 | modifier = Modifier.size(200.dp), 67 | onCircleClick = { segment -> 68 | println("Clicked on: ${segment.label} (${segment.value})") 69 | } 70 | ) 71 | 72 | ``` -------------------------------------------------------------------------------- /docs/charts/comparison_bar_chart.md: -------------------------------------------------------------------------------- 1 | # `ComparisonBarChart` 2 | 3 | ![comparisonchart_01.png](../site/img/bar/comparisonchart_01.png) 4 | 5 | ## 🍸Overview 6 | A chart that displays a **grouped bar chart** for comparing multiple values across common categories (e.g., monthly comparisons for different products, users, or metrics). Each group represents a category and contains multiple bars to compare distinct values within that group. 7 | 8 | ## 🧱 Declaration 9 | 10 | ```kotlin 11 | @Composable 12 | fun ComparisonBarChart( 13 | data: () -> List, 14 | modifier: Modifier = Modifier, 15 | labelConfig: LabelConfig = LabelConfig.default(), 16 | comparisonBarChartConfig: ComparisonBarChartConfig = ComparisonBarChartConfig.default(), 17 | onGroupClicked: (Int) -> Unit = {} 18 | ) 19 | ``` 20 | 21 | ## 🔧 Parameters 22 | 23 | | Parameter | Type | Description | 24 | |----------------------------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------| 25 | | `data` | `() -> List` | A lambda that returns a list of `ComparisonBarData` items. Each item defines a group with one or more bars for comparison. | 26 | | `modifier` | `Modifier` | Compose `Modifier` to control layout, padding, size, or drawing behavior. | 27 | | `labelConfig` | `LabelConfig` | Configuration for the X-axis and Y-axis labels, including font size, color, alignment, etc. | 28 | | `comparisonBarChartConfig` | `ComparisonBarChartConfig` | Defines visual properties and behavior of the grouped bar chart like bar spacing, animation, alignment, max value, etc. | 29 | | `onGroupClicked` | `(Int) -> Unit` | Callback triggered when a group (set of bars) is clicked. Receives the index of the clicked group. Useful for interactivity or detail views. | 30 | 31 | --- 32 | 33 | ## 📊 `ComparisonBarData` Model 34 | 35 | A data class representing a single group in a comparison bar chart. Each group corresponds to a label (e.g., a category or time period) and contains multiple bars with individual values and colors for comparison within that group. 36 | 37 | ```kotlin 38 | data class ComparisonBarData( 39 | val label: String, 40 | val bars: List, 41 | val colors: List 42 | ) 43 | ``` 44 | | Property | Type | Description | 45 | |----------|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| 46 | | `label` | `String` | The label representing the group on the X-axis. Common examples include month names, category names, or dates. | 47 | | `bars` | `List` | A list of `Float` values representing the height of each bar in the group. The number of values in this list determines how many bars are shown for the group. | 48 | | `colors` | `List` | A list of `ChartColor` values that define the fill color for each corresponding bar in the `bars` list. Should match the size of `bars` for consistent rendering. | 49 | 50 | ## 💡 Example 51 | 52 | ```kotlin 53 | val chartData = listOf( 54 | ComparisonBarData( 55 | label = "Jan", 56 | bars = listOf( 57 | BarData(yValue = 50f, xValue = "Product A", barColor = Color.Red.asSolidChartColor()), 58 | BarData(yValue = 75f, xValue = "Product B", barColor = Color.Blue.asSolidChartColor()) 59 | ) 60 | ), 61 | ComparisonBarData( 62 | label = "Feb", 63 | bars = listOf( 64 | BarData(yValue = 60f, xValue = "Product A", barColor = Color.Red.asSolidChartColor()), 65 | BarData(yValue = 85f, xValue = "Product B", barColor = Color.Blue.asSolidChartColor()) 66 | ) 67 | ) 68 | ) 69 | 70 | ComparisonBarChart( 71 | data = { chartData }, 72 | modifier = Modifier.fillMaxWidth(), 73 | onGroupClicked = { index -> 74 | 75 | } 76 | ) 77 | ``` -------------------------------------------------------------------------------- /docs/charts/horizontal_bar_chart.md: -------------------------------------------------------------------------------- 1 | # `HorizontalBarChart` 2 | 3 | | ![horizontalChart_01.png](../site/img/bar/horizontalChart_01.png) | ![horizontalChart_02.png](../site/img/bar/horizontalChart_02.png) | 4 | |-------------------------------------------------------------------|-------------------------------------------------------------------| 5 | 6 | ## 🍸Overview 7 | A chart that displays a **horizontal bar chart**, where each bar extends horizontally based on its 8 | data value. This layout is ideal when category labels are long or when you want to emphasize value 9 | comparisons along a vertical list. 10 | 11 | ## 🧱 Declaration 12 | 13 | ```kotlin 14 | @Composable 15 | fun HorizontalBarChart( 16 | data: () -> List, 17 | modifier: Modifier = Modifier, 18 | barChartConfig: BarChartConfig = BarChartConfig.default(), 19 | barChartColorConfig: BarChartColorConfig = BarChartColorConfig.default(), 20 | horizontalBarLabelConfig: HorizontalBarLabelConfig = HorizontalBarLabelConfig.default(), 21 | onBarClick: (BarData) -> Unit = {} 22 | ) 23 | ``` 24 | 25 | ## 🔧 Parameters 26 | 27 | | Parameter | Type | Description | 28 | |----------------------------|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| 29 | | `data` | `() -> List` | A lambda that returns the list of `BarData` entries to be displayed as horizontal bars. Each `BarData` contains the Y-value (bar length) and X-value (label/key). | 30 | | `modifier` | `Modifier` | Compose `Modifier` for layout control, sizing, padding, or other UI decorations. | 31 | | `barChartConfig` | `BarChartConfig` | Configuration object for chart behavior and layout — such as minimum number of bars, axis and grid visibility, animation, and spacing. | 32 | | `barChartColorConfig` | `BarChartColorConfig` | Defines color-related customization for bars, axis lines, grid lines, and background. | 33 | | `horizontalBarLabelConfig` | `HorizontalBarLabelConfig` | Styling and layout configuration for the labels displayed alongside the horizontal bars, such as text color, size, alignment, and optional background. | 34 | | `onBarClick` | `(BarData) -> Unit` | Callback function invoked when a bar is clicked. Receives the corresponding `BarData` item for further action (e.g., navigation, tooltip, etc.). | 35 | 36 | ## 📊 Data Model 37 | 38 | Each bar is represented using the `BarData` class: 39 | 40 | ```kotlin 41 | data class BarData( 42 | val yValue: Float, 43 | val xValue: Any, 44 | val barColor: ChartColor = Color.Unspecified.asSolidChartColor(), 45 | val barBackgroundColor: ChartColor = Color(0x40D3D3D3).asSolidChartColor(), 46 | ) 47 | ``` 48 | 49 | ## 🔠 HorizontalBarLabelConfig 50 | 51 | The horizontalBarLabelConfig parameter lets you customize how the labels for each horizontal bar are 52 | rendered. 53 | 54 | ```kotlin 55 | data class HorizontalBarLabelConfig( 56 | val showLabel: Boolean, 57 | val hasOverlappingLabel: Boolean, 58 | val textColor: ChartColor, 59 | val textBackgroundColors: ChartColor, 60 | val xAxisCharCount: Int?, 61 | val labelTextStyle: TextStyle?, 62 | ) 63 | ``` 64 | 65 | > If labels are not shown, users can drag their finger or scroll across the chart to reveal labels 66 | > dynamically via gesture detection. This allows clean visualizations by default, but still gives 67 | > access to detailed information on demand. 68 | 69 | | Property | Type | Description | 70 | |------------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| 71 | | `showLabel` | `Boolean` | Determines whether the label for each horizontal bar should be shown by default. If `false`, labels are hidden unless revealed through gestures (e.g. dragging). | 72 | | `hasOverlappingLabel` | `Boolean` | Indicates whether labels are allowed to overlap with each other. If `true`, labels may render over each other in dense datasets. | 73 | | `textColor` | `ChartColor` | The color of the label text. You can use solid or gradient chart colors. | 74 | | `textBackgroundColors` | `ChartColor` | Background color behind the label text. Useful for adding contrast or highlighting the label. | 75 | | `xAxisCharCount` | `Int?` | Optionally limits the number of characters shown from the X-axis label. Useful for truncation in narrow layouts. If `null`, no truncation is applied. | 76 | | `labelTextStyle` | `TextStyle?` | Custom styling for label text (e.g., font size, weight, family, line height). If `null`, defaults are used. | 77 | 78 | ## 💡 Example Usage 79 | 80 | ```kotlin 81 | val performanceData = listOf( 82 | BarData(yValue = 80f, xValue = "Alice"), 83 | BarData(yValue = 65f, xValue = "Bob"), 84 | BarData(yValue = 90f, xValue = "Charlie") 85 | ) 86 | 87 | HorizontalBarChart( 88 | data = { performanceData }, 89 | modifier = Modifier.fillMaxWidth(), 90 | onBarClick = { bar -> 91 | println("Clicked on ${bar.xValue} with value ${bar.yValue}") 92 | } 93 | ) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/charts/line_bar_chart.md: -------------------------------------------------------------------------------- 1 | # LineBarChart 2 | 3 | ![lineChart_01.png](../site/img/bar/lineChart_01.png) 4 | 5 | ## 🍸Overview 6 | A chart that displays a bar chart with an optional target line overlaid. This chart is useful for showing individual bar values while highlighting a specific target or benchmark using a line (e.g., sales goal, average, or threshold). 7 | 8 | ## 🧱 Declaration 9 | 10 | ```kotlin 11 | @Composable 12 | fun LineBarChart( 13 | data: () -> List, 14 | modifier: Modifier = Modifier, 15 | target: Float? = null, 16 | targetConfig: TargetConfig = TargetConfig.default(), 17 | barChartConfig: BarChartConfig = BarChartConfig.default(), 18 | labelConfig: LabelConfig = LabelConfig.default(), 19 | barChartColorConfig: BarChartColorConfig = BarChartColorConfig.default(), 20 | onBarClick: (Int, BarData) -> Unit = { _, _ -> }, 21 | ) 22 | ``` 23 | 24 | ## 🔧 Parameters 25 | | Parameter | Type | Description | 26 | |-----------------------|--------------------------|------------------------------------------------------------------------------------------------------------------------------| 27 | | `data` | `() -> List` | A lambda function returning the list of bar values to render. Each `BarData` contains the value, label, and color of a bar. | 28 | | `modifier` | `Modifier` | A Jetpack Compose `Modifier` to customize layout, size, padding, etc. | 29 | | `target` | `Float?` | A numerical value representing a target line to be drawn across the chart. If `null`, no target line is shown. | 30 | | `targetConfig` | `TargetConfig` | Configuration object to style and position the target line (e.g., stroke color, width, label). | 31 | | `barChartConfig` | `BarChartConfig` | Controls the layout behavior of the chart including min bar count, animation, axis visibility, and spacing. | 32 | | `labelConfig` | `LabelConfig` | Configuration for customizing the bar labels (position, visibility, text style). | 33 | | `barChartColorConfig` | `BarChartColorConfig` | Defines the colors for bars, axis lines, grid lines, and backgrounds. | 34 | | `onBarClick` | `(Int, BarData) -> Unit` | Lambda called when a user taps on a bar. Provides the index and associated `BarData`. Useful for interactivity and tooltips. | 35 | 36 | ## 📊 Data Model 37 | 38 | ```kotlin 39 | data class BarData( 40 | val yValue: Float, 41 | val xValue: Any, 42 | val barColor: ChartColor = Color.Unspecified.asSolidChartColor(), 43 | val barBackgroundColor: ChartColor = Color(0x40D3D3D3).asSolidChartColor(), 44 | ) 45 | ``` 46 | 47 | ## 🔠 Target 48 | - Use the target parameter to draw a horizontal reference line across the chart. 49 | - Ideal for benchmarks, goals, or thresholds (e.g., expected sales, performance targets). 50 | - Styled using TargetConfig, which allows customizing: 51 | - Color and stroke width 52 | - Dashed/solid appearance 53 | - Label and label positioning 54 | 55 | ## 💡 Example Usage 56 | 57 | ```kotlin 58 | LineBarChart( 59 | data = { 60 | listOf( 61 | BarData(80f, "Jan"), 62 | BarData(120f, "Feb"), 63 | BarData(60f, "Mar") 64 | ) 65 | }, 66 | target = 100f, 67 | targetConfig = TargetConfig( 68 | color = Color.Red, 69 | strokeWidth = 2.dp, 70 | showLabel = true, 71 | label = "Target: 100" 72 | ), 73 | onBarClick = { index, bar -> 74 | println("Bar ${index + 1}: ${bar.yValue}") 75 | } 76 | ) 77 | 78 | ``` -------------------------------------------------------------------------------- /docs/charts/line_chart.md: -------------------------------------------------------------------------------- 1 | # `LineChart` 2 | 3 | | Smooth Line Curve | Pointed Line Curve | Line Filled | 4 | |--------------------------------------------------------|--------------------------------------------------------|--------------------------------------------------------| 5 | | ![linechart_02.png](../site/img/line/linechart_02.png) | ![linechart_03.png](../site/img/line/linechart_03.png) | ![linechart_04.png](../site/img/line/linechart_04.png) | 6 | 7 | ## 🍸Overview 8 | 9 | A chart that renders a **line chart** to visualize continuous or time-series data. Supports various 10 | configurations including smooth curves, area fill, stroke lines, interactivity, and targets. 11 | 12 | --- 13 | 14 | ## 🧱 Declaration 15 | 16 | There are **two overloaded versions** of `LineChart`, each offering different forms of interaction: 17 | 18 | ### Version 1: With `onClick` support 19 | 20 | ```kotlin 21 | @Composable 22 | fun LineChart( 23 | data: () -> List, 24 | modifier: Modifier = Modifier, 25 | smoothLineCurve: Boolean = true, 26 | showFilledArea: Boolean = false, 27 | showLineStroke: Boolean = true, 28 | showOnClickBar: Boolean = true, 29 | colorConfig: LineChartColorConfig = LineChartColorConfig.default(), 30 | labelConfig: LabelConfig = LabelConfig.default(), 31 | target: Float? = null, 32 | targetConfig: TargetConfig = TargetConfig.default(), 33 | chartConfig: LineChartConfig = LineChartConfig(), 34 | onClick: (LineData) -> Unit = {} 35 | ) 36 | ``` 37 | 38 | ### Version 2: With `onValueChange` support 39 | 40 | ```kotlin 41 | @Composable 42 | fun LineChart( 43 | data: () -> List, 44 | modifier: Modifier = Modifier, 45 | smoothLineCurve: Boolean = true, 46 | showFilledArea: Boolean = false, 47 | showLineStroke: Boolean = true, 48 | colorConfig: LineChartColorConfig = LineChartColorConfig.default(), 49 | labelConfig: LabelConfig = LabelConfig.default(), 50 | target: Float? = null, 51 | targetConfig: TargetConfig = TargetConfig.default(), 52 | chartConfig: LineChartConfig = LineChartConfig(), 53 | onValueChange: (LineData) -> Unit = {}, 54 | ) 55 | ``` 56 | 57 | --- 58 | 59 | ## 🔧 Parameters 60 | 61 | | Parameter | Type | Description | 62 | |-------------------|------------------------|--------------------------------------------------------------------------------------------------------------------------------------| 63 | | `data` | `() -> List` | Lambda returning a list of `LineData` points representing x/y values to be plotted. | 64 | | `modifier` | `Modifier` | Optional Jetpack Compose modifier for layout styling. | 65 | | `smoothLineCurve` | `Boolean` | If true, curves between data points will be smoothly interpolated using Bézier or spline curves. If false, straight lines are drawn. | 66 | | `showFilledArea` | `Boolean` | If true, the area under the line is filled with gradient or solid color. | 67 | | `showLineStroke` | `Boolean` | If true, a visible line is drawn over the chart representing the data. | 68 | | `showOnClickBar` | `Boolean` | (Only in version 1) If true, shows a vertical indicator when a value is clicked. | 69 | | `colorConfig` | `LineChartColorConfig` | Defines line stroke color, fill color, gradients, and background. | 70 | | `labelConfig` | `LabelConfig` | Manages display and styling of axis or data labels. | 71 | | `target` | `Float?` | Optional horizontal line to show a benchmark or target. | 72 | | `targetConfig` | `TargetConfig` | Configuration of the target line (color, thickness, label, etc). | 73 | | `chartConfig` | `LineChartConfig` | Controls axis visibility, padding, animation, min/max values, etc. | 74 | | `onClick` | `(LineData) -> Unit` | (Only in version 1) Triggered when a data point is clicked. | 75 | | `onValueChange` | `(LineData) -> Unit` | (Only in version 2) Triggered on drag interactions over the line chart. | 76 | 77 | --- 78 | 79 | ## ⚠️ Constraints 80 | 81 | ```kotlin 82 | require(showFilledArea || showLineStroke) { 83 | "Both showFilledArea and showLineStroke cannot be false at the same time" 84 | } 85 | ``` 86 | 87 | At least one of `showFilledArea` or `showLineStroke` **must** be true, otherwise an 88 | `IllegalArgumentException` is thrown. This ensures the chart is visible. 89 | 90 | --- 91 | 92 | ## 📊 Data Model 93 | 94 | Each data point in the chart is represented by the `LineData` class: 95 | 96 | ```kotlin 97 | data class LineData( 98 | val xValue: Any, 99 | val yValue: Float 100 | ) 101 | ``` 102 | 103 | --- 104 | 105 | ## 💡 Example Usage 106 | 107 | ```kotlin 108 | LineChart( 109 | data = { 110 | listOf( 111 | LineData("Jan", 10f), 112 | LineData("Feb", 40f), 113 | LineData("Mar", 25f) 114 | ) 115 | }, 116 | smoothLineCurve = true, 117 | showFilledArea = true, 118 | showLineStroke = true, 119 | target = 30f, 120 | targetConfig = TargetConfig(label = "Average"), 121 | onClick = { lineData -> println("Clicked: ${lineData.xValue} -> ${lineData.yValue}") } 122 | ) 123 | ``` -------------------------------------------------------------------------------- /docs/charts/line_stack_bar_chart.md: -------------------------------------------------------------------------------- 1 | # Line Stacked Bar Chart 2 | 3 | ![line_stack_bar_chart_01.png](../site/img/bar/line_stack_bar_chart_01.png) 4 | 5 | ## 🍸Overview 6 | The `LineStackedBarChart` offers a unique way to visualize stacked data. It's a variation of a standard stacked bar chart, but instead of wider bars, each stack is rendered as a thin vertical line composed of multiple segments. This chart is suitable for showing part-to-whole relationships across multiple categories, with a visually lighter footprint than a standard `StackedBarChart`. 7 | 8 | ## 🧱 Declaration 9 | 10 | ```kotlin 11 | @Composable 12 | fun LineStackedBarChart( 13 | data: () -> List, 14 | modifier: Modifier = Modifier, 15 | target: Float? = null, 16 | targetConfig: TargetConfig = TargetConfig.default(), 17 | stackBarConfig: StackBarConfig = StackBarConfig.default(), 18 | labelConfig: LabelConfig = LabelConfig.default(), 19 | barChartColorConfig: BarChartColorConfig = BarChartColorConfig.default(), 20 | onBarClick: (Int, StackBarData) -> Unit = { _, _ -> } 21 | ) 22 | ``` 23 | 24 | ## 🔧 Parameters 25 | | Parameter | Type | Description | 26 | |-----------------------|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 27 | | `data` | `() -> List` | A lambda function that returns a list of `StackBarData`. Each `StackBarData` object represents a full vertical "line" stack. | 28 | | `modifier` | `Modifier` | A `Modifier` for customizing the layout (e.g., size, padding) of the chart. (Optional) | 29 | | `target` | `Float?` | An optional `Float` value. If provided, a horizontal line will be drawn at this Y-value on the chart. (Optional) | 30 | | `targetConfig` | `TargetConfig` | A `TargetConfig` object for configuring the appearance of the target line. (Optional, defaults to `TargetConfig.default()`) | 31 | | `stackBarConfig` | `StackBarConfig` | A `StackBarConfig` object for configuring chart aspects. Key properties include `showCurvedBar`, `showAxisLines`, `showGridLines`, `minimumBarCount`. (Optional, defaults to `StackBarConfig.default()`) | 32 | | `labelConfig` | `LabelConfig` | A `LabelConfig` object for configuring the appearance of X-axis and Y-axis labels. (Optional, defaults to `LabelConfig.default()`) | 33 | | `barChartColorConfig` | `BarChartColorConfig` | A `BarChartColorConfig` object used here primarily for configuring the colors of axis lines and grid lines. The colors for the stack segments themselves are defined within each `StackBarData` item. (Optional, defaults to `BarChartColorConfig.default()`) | 34 | | `onBarClick` | `(Int, StackBarData) -> Unit` | A lambda function `(Int, StackBarData) -> Unit` that is invoked when a "line" stack is clicked. It receives the index of the clicked stack and the corresponding `StackBarData`. (Optional) | 35 | 36 | ## 🧮 StackBarData Model 37 | 38 | ```kotlin 39 | data class StackBarData( 40 | val label: String, 41 | val values: List, 42 | val colors: List 43 | ) 44 | ``` 45 | | Property | Type | Description | 46 | |----------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 47 | | `label` | `String` | The label for this stack, displayed on the X-axis. | 48 | | `values` | `List` | A list of float values, where each value is a segment in the stack. The height of each segment is proportional to its value relative to the total sum of values in this stack. | 49 | | `colors` | `List` | A list of `ChartColor` for each corresponding segment in `values`. The size of this list should match the `values` list. | 50 | 51 | > You can find a mock implementation in sample module's App file 52 | 53 | ## Example Usage 54 | 55 | ```kotlin 56 | @Composable 57 | fun SampleLineStackedBarChart() { 58 | LineStackedBarChart( 59 | data = { data }, 60 | target = 100f, 61 | modifier = Modifier.fillMaxWidth().height(300.dp).padding(24.dp) 62 | ) 63 | } 64 | ``` -------------------------------------------------------------------------------- /docs/charts/multi_line_chart.md: -------------------------------------------------------------------------------- 1 | # Multi Line Chart 2 | 3 | | Pointed Line Curve | Smooth Line Curve | 4 | |----------------------------------------------------------------|----------------------------------------------------------------| 5 | | ![multiple_line_01.png](../site/img/line/multiple_line_01.png) | ![multiple_line_02.png](../site/img/line/multiple_line_02.png) | 6 | 7 | ## 🍸Overview 8 | 9 | A multi-line chart displays multiple series of data points connected by lines. It is particularly 10 | useful for comparing trends over time or across different categories for several groups 11 | simultaneously. This chart allows for easy visualization of relationships, crossovers, and 12 | divergences between different datasets. 13 | 14 | ## 🧱 Declaration 15 | 16 | ```kotlin 17 | @Composable 18 | fun MultiLineChart( 19 | lines: () -> List, 20 | modifier: Modifier = Modifier, 21 | lineConfig: LineConfig = LineConfig.default(), 22 | xAxisConfig: XAxisConfig = XAxisConfig.default(), 23 | yAxisConfig: YAxisConfig = YAxisConfig.default(), 24 | labelConfig: LabelConfig = LabelConfig.default(), 25 | onPointClick: (lineIndex: Int, pointIndex: Int, point: PointData) -> Unit = { _, _, _ -> } 26 | ) 27 | ``` 28 | 29 | ## 🔧 Parameters 30 | 31 | | Parameter | Type | Description | 32 | |----------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 33 | | `lines` | `() -> List` | A lambda returning the list of `LineData` entries. Each `LineData` defines a separate line with its data points, color, and other properties. | 34 | | `modifier` | `Modifier` | Optional Compose `Modifier` for layout behavior, styling, padding, etc. | 35 | | `lineConfig` | `LineConfig` | Configuration for the appearance of all lines, such as default point visibility, point style, line thickness, and curve rendering (e.g., cubic bezier). Individual `LineData` properties can override some of these. | 36 | | `xAxisConfig` | `XAxisConfig` | Configuration specific to the X-axis, like label formatting, grid lines, and axis line visibility. | 37 | | `yAxisConfig` | `YAxisConfig` | Configuration specific to the Y-axis, including label formatting, value range, grid lines, and axis line visibility. | 38 | | `labelConfig` | `LabelConfig` | Controls how labels for X and Y axes are rendered (font size, visibility, position, color etc.). | 39 | | `onPointClick` | `(lineIndex: Int, pointIndex: Int, point: PointData) -> Unit` | Lambda called when a data point on a line is clicked. Provides indices for the line and point, and the `PointData` itself. Default is no-op. | 40 | 41 | ## 🧮 Data Models 42 | 43 | ### MultiLineData Model 44 | 45 | ```kotlin 46 | data class MultiLineData( 47 | val data: List, 48 | val colorConfig: LineChartColorConfig 49 | ) 50 | ``` 51 | 52 | | Parameter | Type | Description | 53 | |---------------|------------------------|----------------------------------------------------------------------------------------------------| 54 | | `data` | `List` | A list of `LineData` points representing the values to be plotted for this line. | 55 | | `colorConfig` | `LineChartColorConfig` | The color and styling configuration specific to this line, including stroke, fill, gradients, etc. | 56 | 57 | > You can find a mock implementation in sample module's App file 58 | 59 | ## Example Usage 60 | 61 | ```kotlin 62 | @Composable 63 | fun SampleMultiLineChart() { 64 | MultiLineChart( 65 | modifier = Modifier.fillMaxWidth().height(300.dp).padding(16.dp), 66 | lines = { chartLinesData }, 67 | labelConfig = LabelConfig.default().copy( 68 | showXLabel = true, 69 | showYLabel = true 70 | ), 71 | lineConfig = LineConfig.default().copy( 72 | showPoints = true 73 | ), 74 | onPointClick = { lineIndex, pointIndex, point -> } 75 | ) 76 | } 77 | ``` -------------------------------------------------------------------------------- /docs/charts/pie_chart.md: -------------------------------------------------------------------------------- 1 | # PieChart 2 | 3 | | Pointed Line Curve | 4 | |-----------------------------------------------------| 5 | | ![piechart_01.png](../site/img/pie/piechart_01.png) | 6 | 7 | ## 🍸Overview 8 | 9 | This function displays a Pie Chart using a list of PieChartData slices. It supports rendering either a standard pie chart or a donut-style chart (with a hole in the center). Each slice is interactive and can trigger a click callback. 10 | 11 | ## 🧱 Declaration 12 | 13 | ```kotlin 14 | @Composable 15 | fun PieChart( 16 | data: () -> List, 17 | modifier: Modifier = Modifier, 18 | isDonutChart: Boolean = false, 19 | onPieChartSliceClick: (PieChartData) -> Unit = {} 20 | ) 21 | ``` 22 | > isDonutChart is used to make donut of PieChart 23 | 24 | ## 🔧 Parameters 25 | 26 | | Parameter | Type | Description | 27 | |------------------------|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| 28 | | `data` | `() -> List` | A lambda that returns the list of pie slices to display. Each slice is represented by a `PieChartData` object. | 29 | | `modifier` | `Modifier` | A `Modifier` for customizing the layout and appearance of the chart (e.g., size, padding, etc.). | 30 | | `isDonutChart` | `Boolean` | If `true`, the chart is displayed as a **donut** (with a circular center cut out). Default is `false` for a full pie. | 31 | | `onPieChartSliceClick` | `(PieChartData) -> Unit` | Callback invoked when a slice is clicked, providing the clicked `PieChartData` as a parameter. Useful for interactivity like tooltips or data inspection. | 32 | 33 | ## 🧮 PieChartData Model 34 | 35 | ```kotlin 36 | data class PieChartData( 37 | val value: Float, 38 | val color: ChartColor, 39 | val labelColor: ChartColor = Color.White.asSolidChartColor(), 40 | val label: String, 41 | ) 42 | ``` 43 | 44 | | Parameter | Type | Description | 45 | |--------------|--------------|---------------------------------------------------------------------------------------------| 46 | | `value` | `Float` | The numeric value of the slice. This determines the size (angle) of the slice in the chart. | 47 | | `color` | `ChartColor` | The fill color of the slice. Can be solid or gradient depending on implementation. | 48 | | `labelColor` | `ChartColor` | The color of the text label associated with the slice. Defaults to white (`Color.White`). | 49 | | `label` | `String` | The textual label to display for the slice. Typically shown in or near the slice. | 50 | 51 | > You can find a mock implementation in sample module's App file 52 | 53 | ## Example Usage 54 | 55 | ```kotlin 56 | @Composable 57 | fun SamplePieChart() { 58 | PieChart( 59 | data = { samplePieData }, 60 | isDonutChart = true, 61 | onPieChartSliceClick = { slice -> println("Clicked: ${slice.label}") }, 62 | modifier = Modifier.size(200.dp) 63 | ) 64 | } 65 | ``` -------------------------------------------------------------------------------- /docs/charts/point_chart.md: -------------------------------------------------------------------------------- 1 | # `PointChart` 2 | 3 | | Point Chart Preview | 4 | |-----------------------------------------------------------| 5 | | ![pointChart_01.png](../site/img/point/pointChart_01.png) | 6 | 7 | ## 🍸Overview 8 | Renders a point chart where each data point is plotted on a 2D axis, useful for visualizing discrete 9 | data points without connecting lines. 10 | 11 | --- 12 | 13 | ## 🧱 Declaration 14 | 15 | ```kotlin 16 | @Composable 17 | fun PointChart( 18 | data: () -> List, 19 | modifier: Modifier = Modifier, 20 | labelConfig: LabelConfig = LabelConfig.default(), 21 | colorConfig: PointChartColorConfig = PointChartColorConfig.default(), 22 | chartConfig: PointChartConfig = PointChartConfig(), 23 | target: Float? = null, 24 | targetConfig: TargetConfig = TargetConfig.default(), 25 | onPointClick: (Int, PointData) -> Unit = { _, _ -> } 26 | ) 27 | ``` 28 | 29 | ## 🔧 Parameters 30 | 31 | | Parameter | Type | Description | 32 | |----------------|----------------------------|------------------------------------------------------------------------------------------------------------------------| 33 | | `data` | `() -> List` | Lambda returning the list of data points to plot. Each `PointData` contains the position and optional visual settings. | 34 | | `modifier` | `Modifier` | Modifier to control layout, size, and gestures. | 35 | | `labelConfig` | `LabelConfig` | Configuration for axis labels and styling. | 36 | | `colorConfig` | `PointChartColorConfig` | Defines color configuration for points, axes, and grid. | 37 | | `chartConfig` | `PointChartConfig` | Visual and animation configuration for the chart (see below). | 38 | | `target` | `Float?` | Optional target line (e.g. goal threshold) shown on the chart. | 39 | | `targetConfig` | `TargetConfig` | Styling for the optional target line. | 40 | | `onPointClick` | `(Int, PointData) -> Unit` | Callback when a point is tapped. Provides index and data point. | 41 | 42 | --- 43 | 44 | ## 📊 Data Model 45 | 46 | ### PointData 47 | 48 | Each data point in the chart is represented by the `PointData` class: 49 | 50 | ```kotlin 51 | data class PointData( 52 | val yValue: Float, 53 | val xValue: Any, 54 | ) 55 | ``` 56 | 57 | ### ⚙️ PointChartConfig 58 | 59 | Configuration options for customizing the appearance and animation of a PointChart. 60 | 61 | ```kotlin 62 | data class PointChartConfig( 63 | val axisLineWidth: Float = 2f, 64 | val gridLineWidth: Float = 1f, 65 | val circleRadius: Float = 10f, 66 | val showClickedBar: Boolean = true, 67 | val animationDurationMillis: Int = 500, 68 | val animationEasing: Easing = LinearEasing, 69 | val animatePoints: Boolean = true, 70 | val gridLinePathEffect: PathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f), 71 | ) 72 | ``` 73 | 74 | | Parameter | Type | Description | 75 | |---------------------------|--------------|-------------------------------------------------------------------| 76 | | `axisLineWidth` | `Float` | Width of the X and Y axis lines. | 77 | | `gridLineWidth` | `Float` | Width of the horizontal/vertical grid lines. | 78 | | `circleRadius` | `Float` | Radius of each plotted point on the chart. | 79 | | `showClickedBar` | `Boolean` | Whether to visually highlight the selected/clicked point. | 80 | | `animationDurationMillis` | `Int` | Duration of the entry animation for points. | 81 | | `animationEasing` | `Easing` | The easing function used during animation. | 82 | | `animatePoints` | `Boolean` | If true, points animate when the chart is first drawn. | 83 | | `gridLinePathEffect` | `PathEffect` | The pattern used for drawing grid lines, default is dashed lines. | 84 | 85 | --- 86 | 87 | ## 💡 Example Usage 88 | 89 | ```kotlin 90 | PointChart( 91 | data = { data }, 92 | target = 18f, 93 | colorConfig = PointChartColorConfig.default(), 94 | chartConfig = PointChartConfig(circleRadius = 20F), 95 | modifier = Modifier.padding(10.dp).fillMaxWidth().height(300.dp), 96 | onPointClick = { index, circleData -> } 97 | ) 98 | ``` -------------------------------------------------------------------------------- /docs/charts/signal_bar_chart.md: -------------------------------------------------------------------------------- 1 | ## 📶 `SignalProgressBarChart` 2 | 3 | ![signalbar.png](../site/img/signalbar.png) 4 | 5 | ## 🍸Overview 6 | A simple **signal-style bar chart** that displays progress using vertically stacked blocks. Visually resembles mobile network signal indicators. 7 | 8 | ## 🧱 Declaration 9 | 10 | ```kotlin 11 | @Composable 12 | fun SignalProgressBarChart( 13 | progress: () -> Float, 14 | maxProgress: Float = 100F, 15 | modifier: Modifier = Modifier, 16 | totalBlocks: Int = 10, 17 | trackColor: ChartColor = Color.Gray.asSolidChartColor(), 18 | progressColor: ChartColor = Color.Green.asSolidChartColor(), 19 | gapRatio: Float = 0.1F 20 | ) 21 | ``` 22 | 23 | --- 24 | 25 | ### 🔧 Parameters 26 | 27 | | Parameter | Type | Description | 28 | | --- | --- | --- | 29 | | `progress` | `() -> Float` | Lambda returning the current progress value. | 30 | | `maxProgress` | `Float` | Maximum possible progress. Default is `100f`. | 31 | | `modifier` | `Modifier` | Modifier to customize layout, size, gesture, etc. | 32 | | `totalBlocks` | `Int` | Total number of vertical blocks in the chart. | 33 | | `trackColor` | `ChartColor` | Color of the unfilled (track) blocks. | 34 | | `progressColor` | `ChartColor` | Color of the filled (progress) blocks. | 35 | | `gapRatio` | `Float` | Fraction of space between each block relative to its height (0.1 = 10% gap). | 36 | 37 | --- 38 | 39 | ### 💡 Notes 40 | 41 | - The blocks fill vertically from bottom to top based on `progress / maxProgress`. 42 | - Useful for visual indicators such as **signal strength**, **step completion**, or **tiered progress**. 43 | - The `gapRatio` allows customization of spacing between blocks for a tighter or more spaced-out look. 44 | - You can pass a dynamic `progress` lambda to animate or update progress in real time. 45 | 46 | --- 47 | 48 | ### 📌 Example 49 | 50 | ```kotlin 51 | SignalProgressBarChart( 52 | progress = { 40f }, 53 | maxProgress = 100f, 54 | totalBlocks = 5, 55 | progressColor = Color.Blue.asSolidChartColor(), 56 | trackColor = Color.LightGray.asSolidChartColor(), 57 | gapRatio = 0.15f 58 | ) 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/charts/speedometer_progress_bar.md: -------------------------------------------------------------------------------- 1 | ## 🧭 `SpeedometerProgressBar` 2 | 3 | ![speedometer.png](../site/img/speedometer.png) 4 | 5 | ## 🍸Overview 6 | A circular **speedometer-style progress bar** with animated progress, customizable colors, arc dots, and center text. Ideal for dashboards, gauges, or motivational UI components. 7 | 8 | ## 🧱 Declaration 9 | 10 | ```kotlin 11 | @Composable 12 | fun SpeedometerProgressBar( 13 | progress: () -> Float, 14 | title: String, 15 | color: ChartColor, 16 | progressIndicatorColor: ChartColor, 17 | trackColor: ChartColor, 18 | modifier: Modifier = Modifier, 19 | dotConfig: DotConfig = DotConfig.default(), 20 | titleTextConfig: TextConfig = TextConfig.default(), 21 | subTitleTextConfig: TextConfig = TextConfig.default(fontSize = 20.sp), 22 | ) 23 | ``` 24 | 25 | --- 26 | 27 | ### 🔧 Parameters 28 | 29 | | Parameter | Type | Description | 30 | | --- | --- | --- | 31 | | `progress` | `() -> Float` | Lambda returning progress between `0f` and `1f`. | 32 | | `title` | `String` | Text shown at the center of the speedometer. | 33 | | `color` | `ChartColor` | Color of the progress arc. | 34 | | `progressIndicatorColor` | `ChartColor` | Color of the indicator circle on the arc. | 35 | | `trackColor` | `ChartColor` | Color of the background arc (track). | 36 | | `modifier` | `Modifier` | Modifier for size, padding, and gesture handling. | 37 | | `dotConfig` | `DotConfig` | Configuration for arc dots (size, count, spacing). | 38 | | `titleTextConfig` | `TextConfig` | Typography for the main title text. | 39 | | `subTitleTextConfig` | `TextConfig` | Typography for optional subtitle or progress info. | 40 | 41 | --- 42 | 43 | ### ✨ Features 44 | 45 | - 🌀 Smooth animated arc indicating progress. 46 | - 🟢 Optional indicator dot moves with progress. 47 | - 🔘 Decorative dots along the arc using `DotConfig`. 48 | - 🔤 Centered title + subtitle text using `TextConfig`. 49 | - 🔄 Fully customizable using modifiers and color configs. 50 | 51 | 52 | --- 53 | 54 | ### 📌 Example 55 | 56 | ```kotlin 57 | SpeedometerProgressBar( 58 | progress = { 0.65f }, 59 | title = "65%", 60 | color = Color.Green.asSolidChartColor(), 61 | progressIndicatorColor = Color.Black.asSolidChartColor(), 62 | trackColor = Color.LightGray.asSolidChartColor(), 63 | dotConfig = DotConfig(count = 30), 64 | titleTextConfig = TextConfig(fontSize = 24.sp, fontWeight = FontWeight.Bold), 65 | subTitleTextConfig = TextConfig(fontSize = 14.sp, color = Color.Gray) 66 | ) 67 | ``` -------------------------------------------------------------------------------- /docs/charts/stack_bar_chart.md: -------------------------------------------------------------------------------- 1 | 📊 StackedBarChart 2 | 3 | ![storagebar.png](../site/img/bar/storagebar.png) 4 | 5 | ## 🍸Overview 6 | A bar that renders a horizontal storage bar, where each segment represents a portion of total usage (like memory, disk, or category breakdowns). The segments are color-coded and interactive. 7 | 8 | ## 🧱 Declaration 9 | 10 | ```kotlin 11 | @Composable 12 | fun StorageBar( 13 | data: () -> List, 14 | trackColor: ChartColor = Color(0xD3D3D3DE).asSolidChartColor(), 15 | modifier: Modifier = Modifier, 16 | onClick: (StorageData) -> Unit = {} 17 | ) 18 | ``` 19 | 20 | ## 🔧 Parameters 21 | 22 | | Parameter | Type | Description | 23 | |--------------|---------------------------|----------------------------------------------------------------------------------------| 24 | | `data` | `() -> List` | Lambda returning a list of segments. Each segment contains a value and category info. | 25 | | `trackColor` | `ChartColor` | The background track color behind all segments. Defaults to light gray. | 26 | | `modifier` | `Modifier` | Modifier for layout and styling customization. | 27 | | `onClick` | `(StorageData) -> Unit` | Callback triggered when a segment is tapped. Provides the corresponding `StorageData`. | 28 | 29 | ## 📊 Data Model 30 | StorageData consists of multiple segments: 31 | 32 | ```kotlin 33 | data class StorageData( 34 | val label: String, 35 | val value: Float, 36 | val color: ChartColor 37 | ) 38 | ``` 39 | - label: The category name (e.g., "Photos", "Apps"). 40 | - value: Proportional value for this segment. 41 | - color: The color representing this category in the bar. 42 | 43 | ### ✨ Features 44 | - 📊 Proportional segments based on total value. 45 | - 🎨 Custom color for each segment. 46 | - 🖱️ Interactive — tap on a segment to receive the related `StorageData`. 47 | - 🎚️ Full-width visual indicator bar with background track color. 48 | 49 | 50 | --- 51 | 52 | ### 📌 Example 53 | 54 | ```kotlin 55 | StorageBar( 56 | data = { 57 | listOf( 58 | StorageData("Photos", 40f, Color.Blue.asSolidChartColor()), 59 | StorageData("Apps", 30f, Color.Red.asSolidChartColor()), 60 | StorageData("Other", 30f, Color.Gray.asSolidChartColor()) 61 | ) 62 | }, 63 | trackColor = Color.LightGray.asSolidChartColor(), 64 | onClick = { segment -> println("Clicked: ${segment.label}") } 65 | ) 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/charts/storage_bar.md: -------------------------------------------------------------------------------- 1 | 🧮 StorageBar 2 | 3 | # Overview 4 | A composable function that displays a storage bar. This type of chart is typically used to visualize proportions of a whole, such as disk space usage where different categories (e.g., photos, apps, documents) consume parts of the total storage. The segments are laid out horizontally, and their widths are proportional to their values. 5 | 6 | # Usage 7 | Key parameters for using this chart: 8 | 9 | - **`data`**: A lambda function that returns a list of `StorageData`. Each `StorageData` object represents a segment in the bar and should contain: 10 | - `value`: A `Float` representing the proportion or amount of this segment relative to others. The actual width will be calculated based on the sum of all values. 11 | - `color`: A `ChartColor` for this segment. 12 | - **`trackColor`**: The `ChartColor` for the unfilled portion of the bar, displayed if the sum of the `value` properties in `data` does not fill the entire available width. (Optional, defaults to `Color(0xD3D3D3DE)`) 13 | - **`modifier`**: A `Modifier` for customizing the layout or drawing behavior of the chart, typically used to set its height, as the width is often `fillMaxWidth`. (Optional) 14 | - **`onClick`**: A lambda function that is invoked when a segment of the bar is clicked. It receives the `StorageData` of the clicked segment. (Optional) 15 | 16 | The corners of the first and last segments can be rounded. Clicking a segment can also slightly increase its height for emphasis. 17 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Charty 2 | 3 | ![Charty Banner](site/img/banner.png) 4 | 5 | Charty is a modern charting library for Kotlin Multiplatform, designed to help you easily conjure beautiful and interactive charts for your applications, much like a wizard casting spells in the world of Harry Potter📜🔮. 6 | 7 | ## Getting Started 8 | 9 | ### Version Catalog 10 | 11 | If you're using Version Catalog, you can configure the dependency by adding it to your 12 | `libs.versions.toml` file as follows: 13 | 14 | ```toml 15 | [versions] 16 | #... 17 | charty = "" 18 | 19 | [libraries] 20 | #... 21 | charty = { module = "com.himanshoe:charty", version.ref = "charty" } 22 | ``` 23 | 24 | ### Gradle 25 | 26 | Add the dependency below to your **module**'s `build.gradle.kts` file: 27 | 28 | ```gradle 29 | dependencies { 30 | implementation("com.himanshoe:charty:$version") 31 | 32 | // if you're using Version Catalog 33 | implementation(libs.charty) 34 | } 35 | ``` 36 | 37 | For Kotlin Multiplatform, add the dependency below to your commonMain source set's 38 | `build.gradle.kts` file: 39 | 40 | ```gradle 41 | sourceSets { 42 | commonMain.dependencies { 43 | implementation(libs.charty) 44 | } 45 | } 46 | ``` 47 | 48 | Find the latest release version [here](https://github.com/hi-manshu/Charty/releases) -------------------------------------------------------------------------------- /docs/site/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

404

8 |

Page not found

9 |

Home

10 |
11 |
12 | 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /docs/site/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/__init__.py -------------------------------------------------------------------------------- /docs/site/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% if config.site_description %}{% endif %} 9 | {% if config.site_author %}{% endif %} 10 | {% if page.canonical_url %}{% endif %} 11 | 12 | 13 | {% block htmltitle %} 14 | {% if page.title %}{{ page.title }} - {% endif %}{{ config.site_name }} 15 | {% endblock %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% if config.theme.highlightjs is defined and config.theme.highlightjs is sameas false %} 27 | 28 | {% else %} 29 | {% if config.theme.colorscheme %} 30 | 31 | {% else %} 32 | 33 | {% endif %} 34 | {% endif %} 35 | 36 | {%- for path in config['extra_css'] %} 37 | 38 | {%- endfor %} 39 | 40 | 41 | 45 | 46 | {% if config.google_analytics %} 47 | 63 | {% endif %} 64 | 65 | {% block extrahead %} {% endblock %} 66 | 67 | 68 | 69 | 70 | {% include "nav.html" %} 71 | 72 |
73 | {% block content %} 74 | {% if page.meta.disable_toc %} 75 |
{% include "content.html" %}
76 | {% else %} 77 |
{% include "toc.html" %}
78 |
{% include "content.html" %}
79 | {% endif %} 80 | {% endblock %} 81 |
82 | 83 | {% if not config.theme.disable_footer %} 84 |
85 | {% block footer %} 86 | {% if not config.theme.disable_footer_except_revision %} 87 |
88 |

{% if config.copyright %} 89 | {{ config.copyright }}
90 | {% endif %} 91 | Documentation built with MkDocs. 92 |

93 | {% endif %} 94 | 95 | {% if page and page.meta.revision_date %} 96 | {% if config.theme.disable_footer_except_revision %}
{% else %}
{% endif %} 97 | Revised on: {{ page.meta.revision_date }} 98 | {% endif %} 99 | {% endblock %} 100 |
101 | {% endif %} 102 | 103 | {%- block scripts %} 104 | 105 | 106 | 107 | {% if config.theme.highlightjs is defined and config.theme.highlightjs is sameas false %} 108 | 109 | {% else %} 110 | 111 | {% if config.theme.hljs_languages %} 112 | {%- for lang in config.theme.hljs_languages %} 113 | 114 | {%- endfor %} 115 | {% endif %} 116 | 117 | {% endif %} 118 | 119 | 120 | {% if config.shortcuts %} 121 | 122 | {% endif %} 123 | 124 | {%- for path in config['extra_javascript'] %} 125 | 126 | {%- endfor %} 127 | {%- endblock %} 128 | 129 | {% if 'search' in config['plugins'] %}{%- include "search-modal.html" %}{% endif %} 130 | {%- include "keyboard-modal.html" %} 131 | 132 | 133 | 134 | {% if page and page.is_homepage %} 135 | 139 | {% endif %} 140 | -------------------------------------------------------------------------------- /docs/site/content.html: -------------------------------------------------------------------------------- 1 | {% if page.meta.source %} 2 | 7 | {% endif %} 8 | 9 | {{ page.content }} 10 | -------------------------------------------------------------------------------- /docs/site/css/base.min.css: -------------------------------------------------------------------------------- 1 | html{scroll-padding-top:70px}body{padding-top:70px}p>img{max-width:100%;height:auto}ul.nav li.first-level{font-weight:bold}ul.nav li.third-level{padding-left:12px}div.col-md-3{padding-left:0}div.col-md-9{padding-bottom:100px}div.source-links{float:right}.bs-sidebar.affix{position:static}.bs-sidebar.well{padding:0}.bs-sidenav{margin-top:30px;margin-bottom:30px;padding-top:10px;padding-bottom:10px;border-radius:5px}.bs-sidebar .nav>li>a{display:block;padding:5px 20px;z-index:1}.bs-sidebar .nav>li>a:hover,.bs-sidebar .nav>li>a:focus{text-decoration:none;border-right:1px solid}.bs-sidebar .nav>.active>a,.bs-sidebar .nav>.active:hover>a,.bs-sidebar .nav>.active:focus>a{font-weight:bold;background-color:transparent;border-right:1px solid}.bs-sidebar .nav .nav{display:none;margin-bottom:8px}.bs-sidebar .nav .nav>li>a{padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%}@media(min-width:992px){.bs-sidebar .nav>.active>ul{display:block}.bs-sidebar.affix,.bs-sidebar.affix-bottom{width:213px}.bs-sidebar.affix{position:fixed;top:80px;max-height:calc(100% - 180px);overflow-y:auto}.bs-sidebar.affix-bottom{position:absolute}.bs-sidebar.affix-bottom .bs-sidenav,.bs-sidebar.affix .bs-sidenav{margin-top:0;margin-bottom:0}}@media(min-width:1200px){.bs-sidebar.affix-bottom,.bs-sidebar.affix{width:263px}}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:0;margin-left:0}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:00px}.bs-callout{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px;background-color:#fcfdff}.bs-callout h4{font-style:normal;font-weight:400;margin-top:0;margin-bottom:5px}.bs-callout p:last-child{margin-bottom:0}.bs-callout code{border-radius:3px}.bs-callout+.bs-callout{margin-top:-5px}.bs-callout-default{border-left-color:#fa023c}.bs-callout-default h4{color:#fa023c}.bs-callout-primary{border-left-color:#428bca}.bs-callout-primary h4{color:#428bca}.bs-callout-success{border-left-color:#5cb85c}.bs-callout-success h4{color:#5cb85c}.bs-callout-danger{border-left-color:#d9534f}.bs-callout-danger h4{color:#d9534f}.bs-callout-warning{border-left-color:#f0ad4e}.bs-callout-warning h4{color:#f0ad4e}.bs-callout-info{border-left-color:#5bc0de}.bs-callout-info h4{color:#5bc0de}.headerlink{display:none;padding-left:.5em}h1:hover .headerlink,h2:hover .headerlink,h3:hover .headerlink,h4:hover .headerlink,h5:hover .headerlink,h6:hover .headerlink{display:inline-block}.admonition{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px;background-color:#fcfdff}.admonition p:last-child{margin-bottom:0}.admonition code{border-radius:3px}.admonition+.admonition{margin-top:-5px}.admonition.note{border-left-color:#428bca}.admonition.warning{border-left-color:#f0ad4e}.admonition.danger{border-left-color:#d9534f}.admonition-title{font-size:19px;font-style:normal;font-weight:400;margin-top:0;margin-bottom:5px}.admonition.note>.admonition-title{color:#428bca}.admonition.warning>.admonition-title{color:#f0ad4e}.admonition.danger>.admonition-title{color:#d9534f} 2 | -------------------------------------------------------------------------------- /docs/site/css/cinder.css: -------------------------------------------------------------------------------- 1 | /* 2 | Cinder Theme for MkDocs | Copyright 2015 Christopher Simpkins | MIT License 3 | */ 4 | 5 | body { 6 | font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 7 | font-size: 16px; 8 | line-height: 1.7; 9 | background-color: #FFF; 10 | color: #343838; 11 | } 12 | h1, h2, h3, h4, h5, h6 { 13 | font-family:'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; 14 | color: #222; 15 | } 16 | h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { 17 | color: #B1B7B9; 18 | } 19 | 20 | h2 { 21 | margin-top: 35px; 22 | } 23 | 24 | h1, h2 { 25 | font-weight: 700; 26 | } 27 | h4 { 28 | font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; 29 | font-weight: 300; 30 | margin-top: 20px; 31 | font-style: italic; 32 | } 33 | h5 { 34 | font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; 35 | font-weight: 300; 36 | font-variant: small-caps; 37 | } 38 | pre, code { 39 | background-color: #FCFDFF; 40 | } 41 | pre>code { 42 | font-size: 13px; 43 | } 44 | pre { 45 | margin-top: 25px; 46 | margin-bottom: 25px; 47 | } 48 | .lead { 49 | font-family:"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; 50 | font-weight: 400; 51 | line-height: 1.4; 52 | letter-spacing: 0.0312em; 53 | color: #B1B7B9; 54 | } 55 | .navbar-default { 56 | background-color: #343838; 57 | border-bottom: 8px #EBF2F2 solid; 58 | } 59 | .bs-sidenav { 60 | background-image: url("../img/grid11.png"); 61 | background-repeat: repeat; 62 | font-family: Inter,"Helvetica Neue",Helvetica,Arial,sans-serif; 63 | font-size: 13px; 64 | } 65 | .well { 66 | background-color: #FCFDFF; 67 | } 68 | .btn-default { 69 | background-color:#FCFDFF; 70 | } 71 | .table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th { 72 | background-color: #FCFDFF; 73 | } 74 | #mkdocs-search-query:focus { 75 | outline: none; 76 | -webkit-box-shadow: none; 77 | box-shadow: none; 78 | } 79 | #mkdocs-search-query { 80 | font-family:"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; 81 | font-size: 20px; 82 | font-weight: 700; 83 | color: #343838; 84 | height: 45px; 85 | } 86 | footer > hr { 87 | width: 35%; 88 | } 89 | -------------------------------------------------------------------------------- /docs/site/css/cinder.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;line-height:1.7;background-color:#FFF;color:#343838}h1,h2,h3,h4,h5,h6{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;color:#222}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{color:#b1b7b9}h2{margin-top:35px}h1,h2{font-weight:700}h4{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;margin-top:20px;font-style:italic}h5{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;font-variant:small-caps}pre,code{background-color:#fcfdff}pre>code{font-size:13px}pre{margin-top:25px;margin-bottom:25px}.lead{font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:400;line-height:1.4;letter-spacing:.0312em;color:#b1b7b9}.navbar-default{background-color:#343838;border-bottom:8px #ebf2f2 solid}.bs-sidenav{background-image:url("../img/grid11.png");background-repeat:repeat;font-family:Inter,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px}.well{background-color:#fcfdff}.btn-default{background-color:#fcfdff}.table-striped>tbody>tr:nth-child(2n+1)>td,.table-striped>tbody>tr:nth-child(2n+1)>th{background-color:#fcfdff}#mkdocs-search-query:focus{outline:0;-webkit-box-shadow:none;box-shadow:none}#mkdocs-search-query{font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:20px;font-weight:700;color:#343838;height:45px}footer>hr{width:35%} 2 | -------------------------------------------------------------------------------- /docs/site/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #FCFDFF; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #998; 18 | font-style: italic; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-subst { 24 | color: #333; 25 | font-weight: bold; 26 | } 27 | 28 | .hljs-number, 29 | .hljs-literal, 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-tag .hljs-attr { 33 | color: #008080; 34 | } 35 | 36 | .hljs-string, 37 | .hljs-doctag { 38 | color: #d14; 39 | } 40 | 41 | .hljs-title, 42 | .hljs-section, 43 | .hljs-selector-id { 44 | color: #900; 45 | font-weight: bold; 46 | } 47 | 48 | .hljs-subst { 49 | font-weight: normal; 50 | } 51 | 52 | .hljs-type, 53 | .hljs-class .hljs-title { 54 | color: #458; 55 | font-weight: bold; 56 | } 57 | 58 | .hljs-tag, 59 | .hljs-name, 60 | .hljs-attribute { 61 | color: #000080; 62 | font-weight: normal; 63 | } 64 | 65 | .hljs-regexp, 66 | .hljs-link { 67 | color: #009926; 68 | } 69 | 70 | .hljs-symbol, 71 | .hljs-bullet { 72 | color: #990073; 73 | } 74 | 75 | .hljs-built_in, 76 | .hljs-builtin-name { 77 | color: #0086b3; 78 | } 79 | 80 | .hljs-meta { 81 | color: #999; 82 | font-weight: bold; 83 | } 84 | 85 | .hljs-deletion { 86 | background: #fdd; 87 | } 88 | 89 | .hljs-addition { 90 | background: #dfd; 91 | } 92 | 93 | .hljs-emphasis { 94 | font-style: italic; 95 | } 96 | 97 | .hljs-strong { 98 | font-weight: bold; 99 | } 100 | -------------------------------------------------------------------------------- /docs/site/css/highlight.min.css: -------------------------------------------------------------------------------- 1 | .hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#fcfdff}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:bold}.hljs-number,.hljs-literal,.hljs-variable,.hljs-template-variable,.hljs-tag .hljs-attr{color:teal}.hljs-string,.hljs-doctag{color:#d14}.hljs-title,.hljs-section,.hljs-selector-id{color:#900;font-weight:bold}.hljs-subst{font-weight:normal}.hljs-type,.hljs-class .hljs-title{color:#458;font-weight:bold}.hljs-tag,.hljs-name,.hljs-attribute{color:navy;font-weight:normal}.hljs-regexp,.hljs-link{color:#009926}.hljs-symbol,.hljs-bullet{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} 2 | -------------------------------------------------------------------------------- /docs/site/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/site/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/site/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/site/img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/banner.png -------------------------------------------------------------------------------- /docs/site/img/bar/barchart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/barchart_01.png -------------------------------------------------------------------------------- /docs/site/img/bar/comparisonchart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/comparisonchart_01.png -------------------------------------------------------------------------------- /docs/site/img/bar/horizontalChart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/horizontalChart_01.png -------------------------------------------------------------------------------- /docs/site/img/bar/horizontalChart_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/horizontalChart_02.png -------------------------------------------------------------------------------- /docs/site/img/bar/lineChart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/lineChart_01.png -------------------------------------------------------------------------------- /docs/site/img/bar/line_stack_bar_chart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/line_stack_bar_chart_01.png -------------------------------------------------------------------------------- /docs/site/img/bar/stack_bar_chart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/stack_bar_chart_01.png -------------------------------------------------------------------------------- /docs/site/img/bar/storagebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/bar/storagebar.png -------------------------------------------------------------------------------- /docs/site/img/circle/circleChart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/circle/circleChart_01.png -------------------------------------------------------------------------------- /docs/site/img/line/linechart_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/line/linechart_02.png -------------------------------------------------------------------------------- /docs/site/img/line/linechart_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/line/linechart_03.png -------------------------------------------------------------------------------- /docs/site/img/line/linechart_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/line/linechart_04.png -------------------------------------------------------------------------------- /docs/site/img/line/multiple_line_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/line/multiple_line_01.png -------------------------------------------------------------------------------- /docs/site/img/line/multiple_line_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/line/multiple_line_02.png -------------------------------------------------------------------------------- /docs/site/img/pie/piechart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/pie/piechart_01.png -------------------------------------------------------------------------------- /docs/site/img/point/pointChart_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/point/pointChart_01.png -------------------------------------------------------------------------------- /docs/site/img/signalbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/signalbar.png -------------------------------------------------------------------------------- /docs/site/img/speedometer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/docs/site/img/speedometer.png -------------------------------------------------------------------------------- /docs/site/keyboard-modal.html: -------------------------------------------------------------------------------- 1 | 41 | -------------------------------------------------------------------------------- /docs/site/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {# 4 | The entry point for the MkDocs Theme. 5 | 6 | Any theme customisations should override this file to redefine blocks defined in 7 | the various templates. The custom theme should only need to define a main.html 8 | which `{% extends "base.html" %}` and defines various blocks which will replace 9 | the blocks defined in base.html and its included child templates. 10 | #} -------------------------------------------------------------------------------- /docs/site/mkdocs_theme.yml: -------------------------------------------------------------------------------- 1 | cinder_theme: true 2 | 3 | static_templates: 4 | - 404.html 5 | 6 | include_search_page: false 7 | search_index_only: false 8 | 9 | shortcuts: 10 | help: 191 # ? 11 | next: 78 # n 12 | previous: 80 # p 13 | search: 83 # s 14 | -------------------------------------------------------------------------------- /docs/site/nav-sub.html: -------------------------------------------------------------------------------- 1 | {% if not nav_item.children %} 2 |
  • 3 | {{ nav_item.title }} 4 |
  • 5 | {% else %} 6 | 14 | {% endif %} 15 | -------------------------------------------------------------------------------- /docs/site/nav.html: -------------------------------------------------------------------------------- 1 | 78 | -------------------------------------------------------------------------------- /docs/site/search-modal.html: -------------------------------------------------------------------------------- 1 | 28 | -------------------------------------------------------------------------------- /docs/site/toc.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | #Gradle 2 | org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" 3 | org.gradle.caching=true 4 | org.gradle.configuration-cache=true 5 | kotlin.mpp.androidGradlePluginCompatibility.nowarn=true 6 | #Kotlin 7 | kotlin.code.style=official 8 | #Android 9 | android.useAndroidX=true 10 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | agp = "8.9.2" 3 | detektCli = "1.23.8" 4 | detektFormatting = "1.23.8" 5 | kotlin = "2.1.0" 6 | jetbrain-compose = "1.7.3" 7 | androidx-activityCompose = "1.10.1" 8 | publish = "0.31.0" 9 | dokka = "2.0.0" 10 | mkdocs = "1.5.0" 11 | mkdocs-material = "9.0.0" 12 | 13 | [libraries] 14 | detekt-cli = { module = "io.gitlab.arturbosch.detekt:detekt-cli", version.ref = "detektCli" } 15 | dokka = { module = "org.jetbrains.dokka:android-documentation-plugin", version.ref = "dokka" } 16 | detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detektFormatting" } 17 | kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } 18 | androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } 19 | mkdocs = { module = "mkdocs:mkdocs", version.ref = "mkdocs" } 20 | mkdocs-material = { module = "mkdocs-material:mkdocs-material", version.ref = "mkdocs-material" } 21 | 22 | [plugins] 23 | publish = { id = "com.vanniktech.maven.publish", version.ref = "publish" } 24 | dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } 25 | androidApplication = { id = "com.android.application", version.ref = "agp" } 26 | androidLibrary = { id = "com.android.library", version.ref = "agp" } 27 | arturbosch-detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.23.8" } 28 | kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } 29 | composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "jetbrain-compose" } 30 | kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } 31 | compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } 32 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Nov 23 22:57:10 IST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | validateDistributionUrl=true 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 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/banner.png -------------------------------------------------------------------------------- /img/photos/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/photos/1.png -------------------------------------------------------------------------------- /img/photos/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/photos/2.png -------------------------------------------------------------------------------- /img/photos/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/photos/3.png -------------------------------------------------------------------------------- /img/photos/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/photos/4.png -------------------------------------------------------------------------------- /img/photos/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/photos/5.png -------------------------------------------------------------------------------- /img/photos/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/photos/6.png -------------------------------------------------------------------------------- /img/video/android.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/video/android.mp4 -------------------------------------------------------------------------------- /img/video/ios.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/img/video/ios.mp4 -------------------------------------------------------------------------------- /iosApp/Configuration/Config.xcconfig: -------------------------------------------------------------------------------- 1 | TEAM_ID= 2 | BUNDLE_ID=com.himanshoe.sampleiOS 3 | APP_NAME=sampleiOS 4 | -------------------------------------------------------------------------------- /iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/himanshoe.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/himanshoe.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iosApp/iosApp.xcodeproj/xcuserdata/himanshoe.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | iosApp.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "idiom": "universal" 5 | } 6 | ], 7 | "info": { 8 | "author": "xcode", 9 | "version": 1 10 | } 11 | } -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "app-icon-1024.png", 5 | "idiom": "universal", 6 | "platform": "ios", 7 | "size": "1024x1024" 8 | } 9 | ], 10 | "info": { 11 | "author": "xcode", 12 | "version": 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "author": "xcode", 4 | "version": 1 5 | } 6 | } -------------------------------------------------------------------------------- /iosApp/iosApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import SwiftUI 3 | import sample 4 | 5 | struct ComposeView: UIViewControllerRepresentable { 6 | func makeUIViewController(context: Context) -> UIViewController { 7 | MainViewControllerKt.MainViewController() 8 | } 9 | 10 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} 11 | } 12 | 13 | struct ContentView: View { 14 | var body: some View { 15 | ComposeView() 16 | .ignoresSafeArea(.keyboard) // Compose has own keyboard handler 17 | } 18 | } 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /iosApp/iosApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIApplicationSceneManifest 26 | 27 | UIApplicationSupportsMultipleScenes 28 | 29 | 30 | UILaunchScreen 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "author": "xcode", 4 | "version": 1 5 | } 6 | } -------------------------------------------------------------------------------- /iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct iOSApp: App { 5 | var body: some Scene { 6 | WindowGroup { 7 | ContentView() 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Charty 2 | site_author: Charty Contributors 3 | site_url: https://himanshoe.github.io/charty/ 4 | repo_url: https://github.com/himanshoe/charty/ 5 | repo_name: charty 6 | theme: 7 | name: null 8 | custom_dir: 'docs/site' 9 | # Optional: Add a default colorscheme, e.g., github 10 | colorscheme: github 11 | highlightjs: true # Cinder uses highlight.js 12 | # Optional: add common languages for highlighting 13 | hljs_languages: 14 | - yaml 15 | - kotlin 16 | - markdown 17 | markdown_extensions: 18 | - admonition 19 | nav: 20 | - Home: index.md 21 | - Charts: 22 | - Bar Chart: charts/bar_chart.md 23 | - Comparison Bar Chart: charts/comparison_bar_chart.md 24 | - Horizontal Bar Chart: charts/horizontal_bar_chart.md 25 | - Line Bar Chart: charts/line_bar_chart.md 26 | - Line Stack Bar Chart: charts/line_stack_bar_chart.md 27 | - Signal Bar Chart: charts/signal_bar_chart.md 28 | - Stack Bar Chart: charts/stack_bar_chart.md 29 | - Storage Bar: charts/storage_bar.md 30 | - Circle Chart: charts/circle_chart.md 31 | - Speedometer ProgressBar: charts/speedometer_progress_bar.md 32 | - Line Chart: charts/line_chart.md 33 | - Multi-Line Chart: charts/multi_line_chart.md 34 | - Pie Chart: charts/pie_chart.md 35 | - Point Chart: charts/point_chart.md 36 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } -------------------------------------------------------------------------------- /sample/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.compose.desktop.application.dsl.TargetFormat 2 | import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi 3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget 4 | import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig 5 | 6 | plugins { 7 | alias(libs.plugins.kotlinMultiplatform) 8 | alias(libs.plugins.androidApplication) 9 | alias(libs.plugins.composeMultiplatform) 10 | alias(libs.plugins.compose.compiler) 11 | } 12 | 13 | kotlin { 14 | androidTarget { 15 | @OptIn(ExperimentalKotlinGradlePluginApi::class) 16 | compilerOptions { 17 | jvmTarget.set(JvmTarget.JVM_11) 18 | } 19 | } 20 | 21 | listOf( 22 | iosX64(), 23 | iosArm64(), 24 | iosSimulatorArm64() 25 | ).forEach { iosTarget -> 26 | iosTarget.binaries.framework { 27 | baseName = "sample" 28 | isStatic = true 29 | } 30 | } 31 | 32 | jvm("desktop") 33 | 34 | wasmJs { 35 | moduleName = "sample" 36 | browser { 37 | val rootDirPath = project.rootDir.path 38 | val projectDirPath = project.projectDir.path 39 | commonWebpackConfig { 40 | outputFileName = "sample.js" 41 | devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply { 42 | static = (static ?: mutableListOf()).apply { 43 | // Serve sources to debug inside browser 44 | add(rootDirPath) 45 | add(projectDirPath) 46 | } 47 | } 48 | } 49 | } 50 | binaries.executable() 51 | } 52 | 53 | sourceSets { 54 | val desktopMain by getting 55 | 56 | androidMain.dependencies { 57 | implementation(compose.preview) 58 | implementation(libs.androidx.activity.compose) 59 | } 60 | commonMain.dependencies { 61 | implementation(compose.runtime) 62 | implementation(project(":charty")) 63 | //implementation(libs.charty) 64 | implementation(compose.foundation) 65 | implementation(compose.material) 66 | implementation(compose.ui) 67 | implementation(compose.components.resources) 68 | implementation(compose.components.uiToolingPreview) 69 | } 70 | desktopMain.dependencies { 71 | implementation(compose.desktop.currentOs) 72 | // implementation(libs.kotlinx.coroutines.swing) 73 | } 74 | } 75 | } 76 | 77 | android { 78 | namespace = "com.himanshoe.sample" 79 | compileSdk = 35 80 | 81 | defaultConfig { 82 | applicationId = "com.himanshoe.sample" 83 | minSdk = 24 84 | versionCode = 1 85 | versionName = "1.0" 86 | } 87 | packaging { 88 | resources { 89 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 90 | } 91 | } 92 | buildTypes { 93 | getByName("release") { 94 | isMinifyEnabled = false 95 | } 96 | } 97 | compileOptions { 98 | sourceCompatibility = JavaVersion.VERSION_11 99 | targetCompatibility = JavaVersion.VERSION_11 100 | } 101 | } 102 | 103 | dependencies { 104 | debugImplementation(compose.uiTooling) 105 | } 106 | 107 | compose.desktop { 108 | application { 109 | mainClass = "com.himanshoe.sample.MainKt" 110 | 111 | nativeDistributions { 112 | targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) 113 | packageName = "com.himanshoe.sample" 114 | packageVersion = "1.0.0" 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /sample/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /sample/src/androidMain/kotlin/com/himanshoe/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.ui.tooling.preview.Preview 8 | 9 | class MainActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | 13 | setContent { 14 | App() 15 | } 16 | } 17 | } 18 | 19 | @Preview 20 | @Composable 21 | fun AppAndroidPreview() { 22 | App() 23 | } -------------------------------------------------------------------------------- /sample/src/androidMain/kotlin/com/himanshoe/sample/Platform.android.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | import android.os.Build 4 | 5 | class AndroidPlatform : Platform { 6 | override val name: String = "Android ${Build.VERSION.SDK_INT}" 7 | } 8 | 9 | actual fun getPlatform(): Platform = AndroidPlatform() -------------------------------------------------------------------------------- /sample/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-manshu/charty/0b15e25be1f74ea86005b73f1a8bfe7799b0d93e/sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/androidMain/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | KotlinProject 3 | -------------------------------------------------------------------------------- /sample/src/commonMain/composeResources/drawable/compose-multiplatform.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 14 | 18 | 24 | 30 | 36 | -------------------------------------------------------------------------------- /sample/src/commonMain/kotlin/com/himanshoe/sample/Greeting.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | class Greeting { 4 | private val platform = getPlatform() 5 | 6 | fun greet(): String { 7 | return "Hello, ${platform.name}!" 8 | } 9 | } -------------------------------------------------------------------------------- /sample/src/commonMain/kotlin/com/himanshoe/sample/Platform.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | interface Platform { 4 | val name: String 5 | } 6 | 7 | expect fun getPlatform(): Platform -------------------------------------------------------------------------------- /sample/src/desktopMain/kotlin/com/himanshoe/sample/Platform.jvm.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | class JVMPlatform : Platform { 4 | override val name: String = "Java ${System.getProperty("java.version")}" 5 | } 6 | 7 | actual fun getPlatform(): Platform = JVMPlatform() -------------------------------------------------------------------------------- /sample/src/desktopMain/kotlin/com/himanshoe/sample/main.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | import androidx.compose.ui.window.Window 4 | import androidx.compose.ui.window.application 5 | 6 | fun main() = application { 7 | Window( 8 | onCloseRequest = ::exitApplication, 9 | title = "KotlinProject", 10 | ) { 11 | App() 12 | } 13 | } -------------------------------------------------------------------------------- /sample/src/iosMain/kotlin/com/himanshoe/sample/MainViewController.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | import androidx.compose.ui.window.ComposeUIViewController 4 | 5 | fun MainViewController() = ComposeUIViewController { App() } -------------------------------------------------------------------------------- /sample/src/iosMain/kotlin/com/himanshoe/sample/Platform.ios.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | import platform.UIKit.UIDevice 4 | 5 | class IOSPlatform : Platform { 6 | override val name: String = 7 | UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion 8 | } 9 | 10 | actual fun getPlatform(): Platform = IOSPlatform() -------------------------------------------------------------------------------- /sample/src/wasmJsMain/kotlin/com/himanshoe/sample/Platform.wasmJs.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | class WasmPlatform : Platform { 4 | override val name: String = "Web with Kotlin/Wasm" 5 | } 6 | 7 | actual fun getPlatform(): Platform = WasmPlatform() -------------------------------------------------------------------------------- /sample/src/wasmJsMain/kotlin/com/himanshoe/sample/main.kt: -------------------------------------------------------------------------------- 1 | package com.himanshoe.sample 2 | 3 | import androidx.compose.ui.ExperimentalComposeUiApi 4 | import androidx.compose.ui.window.ComposeViewport 5 | import kotlinx.browser.document 6 | 7 | @OptIn(ExperimentalComposeUiApi::class) 8 | fun main() { 9 | ComposeViewport(document.body!!) { 10 | App() 11 | } 12 | } -------------------------------------------------------------------------------- /sample/src/wasmJsMain/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | KotlinProject 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sample/src/wasmJsMain/resources/styles.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | margin: 0; 5 | padding: 0; 6 | overflow: hidden; 7 | } -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 2 | pluginManagement { 3 | repositories { 4 | google() 5 | gradlePluginPortal() 6 | mavenCentral() 7 | } 8 | } 9 | 10 | dependencyResolutionManagement { 11 | repositories { 12 | google() 13 | mavenCentral() 14 | } 15 | } 16 | 17 | rootProject.name = "chartyKMP" 18 | include(":charty") 19 | include(":sample") 20 | --------------------------------------------------------------------------------