{"id":21121601,"url":"https://github.com/ifleey/compose-heatmap","last_synced_at":"2026-03-15T14:08:14.003Z","repository":{"id":262276414,"uuid":"886750050","full_name":"iFleey/Compose-HeatMap","owner":"iFleey","description":"Effortlessly create GitHub-style heatmaps in Jetpack Compose—perfect for visualizing a variety of time-based data patterns.","archived":false,"fork":false,"pushed_at":"2025-02-11T10:08:59.000Z","size":4828,"stargazers_count":12,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-04T21:12:40.279Z","etag":null,"topics":["android","compose","compose-android","compose-desktop","compose-multiplatform","kotlin","kotlin-android","kotlin-multiplatform"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iFleey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-11T14:35:48.000Z","updated_at":"2025-06-26T09:27:20.000Z","dependencies_parsed_at":"2024-11-11T15:39:06.628Z","dependency_job_id":"e9a91340-e35a-4e6d-b3bb-5edc65fd8e0f","html_url":"https://github.com/iFleey/Compose-HeatMap","commit_stats":null,"previous_names":["ifleey/compose-heatmap"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/iFleey/Compose-HeatMap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iFleey%2FCompose-HeatMap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iFleey%2FCompose-HeatMap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iFleey%2FCompose-HeatMap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iFleey%2FCompose-HeatMap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iFleey","download_url":"https://codeload.github.com/iFleey/Compose-HeatMap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iFleey%2FCompose-HeatMap/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264352903,"owners_count":23594992,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose","compose-android","compose-desktop","compose-multiplatform","kotlin","kotlin-android","kotlin-multiplatform"],"created_at":"2024-11-20T03:52:40.284Z","updated_at":"2026-03-15T14:08:13.902Z","avatar_url":"https://github.com/iFleey.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Compose-HeatMap\n\n[![Maven Central](https://img.shields.io/maven-central/v/com.fleeys/heatmap)](https://central.sonatype.com/artifact/com.fleeys/heatmap) ![Android](https://img.shields.io/badge/Platform-Android-brightgreen.svg?logo=android) ![Desktop](https://img.shields.io/badge/Platform-Desktop-8A2BE2.svg?logo=openjdk) ![WasmJS](https://img.shields.io/badge/Platform-WASM%20%2F%20JS-yellow.svg?logo=javascript)\n\nEffortlessly create GitHub-style heatmaps in Jetpack Compose—perfect for visualizing a variety of time-based data patterns.\n\n## Preview\n\n| Platform |                     Default Style                      |                     Custom Style                     |\n| :------: | :----------------------------------------------------: | :--------------------------------------------------: |\n| Android  | ![Default-Style](./images/Android/preview-default.jpg) | ![Custom-Style](./images/Android/preview-custom.jpg) |\n| Desktop  | ![Default-Style](./images/Desktop/preview-default.png) | ![Custom-Style](./images/Desktop/preview-custom.png) |\n|  WasmJs  | ![Default-Style](./images/WasmJs/preview-default.png)  | ![Default-Style](./images/WasmJs/preview-custom.png) |\n\n## Usage\n\nThis project is based on `kotlinx-datetime` for LocalDate-related operations, not `java.time.*`!\n\nrefer to [kotlinx-datetime](https://github.com/Kotlin/kotlinx-datetime) to add dep.\n\n\u003e build.gradle.kts\n\n```kotlin\nimplementation(\"com.fleeys:heatmap:1.0.5\")\n```\n\n\u003e build.gradle\n\n```groovy\nimplementation 'com.fleeys:heatmap:1.0.5'\n```\n\n## Overview\n\n```kotlin\n// ../library/src/commonMain/kotlin/com/fleeys/heatmap/HeatMap.kt\n\n@Composable\nfun \u003cT\u003e HeatMap(\n  modifier: Modifier = Modifier,\n  data: List\u003cHeat\u003cT\u003e\u003e,\n  style: HeatMapStyle = HeatMapStyle(),\n  scrollState: LazyListState = rememberLazyListState(),\n  onScrolledToTop: (() -\u003e Unit)? = null,\n  onScrolledToBottom: (() -\u003e Unit)? = null,\n  onHeatClick: (Heat\u003cT\u003e) -\u003e Unit,\n)\n```\n\n## Features\n\n\n\u003e [!IMPORTANT]  \n\u003e The project is in the experimental phase. All APIs can change incompatibly or be dropped without the deprecation cycle!\n\n### Easy to use\n\nWorks right out of the box without much setup.\n\n```kotlin\n// ../sample/src/commonMain/com/fleeys/heatmap/sample/SampleHeatMap.kt\n\n@Composable\nfun SampleHeatMap() {\n  val scrollState = rememberLazyListState()\n  val coroutineScope = rememberCoroutineScope()\n\n  var heatMapStyle by remember { mutableStateOf\u003cHeatMapStyle?\u003e(null) }\n  val toggleStyle = { heatMapStyle = if (heatMapStyle == null) CustomHeatMapStyle else null }\n\n  Box(\n    modifier = Modifier\n      .fillMaxSize()\n      .background(Color.Black)\n      .padding(16.dp)\n  ) {\n    HeatMap(\n      data = generateHeats(),\n      scrollState = scrollState,\n      style = heatMapStyle ?: HeatMapStyle(),\n      onScrolledToTop = { println(\"Scrolled to Top\") },\n      onScrolledToBottom = { println(\"Scrolled to Bottom\") }\n    ) { println(\"Clicked: $it\") }\n\n    Column(\n      modifier = Modifier\n        .align(Alignment.BottomCenter)\n        .padding(16.dp),\n      horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n      Button(\n        onClick = toggleStyle,\n      ) {\n        Text(\"Toggle Style\")\n      }\n      Button(onClick = {\n        coroutineScope.launch {\n          scrollState.animateScrollToItem(0)\n        }\n      }) {\n        Text(\"Scroll to Top\")\n      }\n\n      Button(onClick = {\n        coroutineScope.launch {\n          scrollState.animateScrollToItem(scrollState.layoutInfo.totalItemsCount - 1)\n        }\n      }) {\n        Text(\"Scroll to Bottom\")\n      }\n    }\n  }\n}\n\n// fake data\nprivate fun generateHeats(): List\u003cHeat\u003cUnit\u003e\u003e {\n  val startDate = LocalDate(2022, 11, 11)\n  val curDate = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date\n\n  return generateSequence(startDate) { date -\u003e\n    if (date \u003c curDate) date + DatePeriod(days = 1) else null\n  }.map { date -\u003e\n    val value = Random.nextDouble(0.0, 32.0)\n    Heat\u003cUnit\u003e(date, value)\n  }.toList()\n}\n```\n\n### Highly customizable\n\nAlmost everything you see can be manipulated.\n\n```kotlin\n// ../library/src/commonMain/kotlin/com/fleeys/heatmap/style/HeatMapStyle.kt\n\n@Immutable\ndata class HeatMapStyle(\n  val heatStyle: HeatStyle = HeatStyle(),\n  val labelStyle: LabelStyle = LabelStyle(),\n  val heatMapPadding: PaddingValues = PaddingValues(0.dp),\n  val startFromEnd: Boolean = true\n)\n\n// Sample Custom Style\n// ../sample/src/commonMain/kotlin/com/fleeys/heatmap/sample/CustomHeatMapStyle.kt\ninternal val CustomHeatMapStyle = HeatMapStyle().copy(\n  heatStyle = HeatStyle().copy(\n    heatColor = HeatColor().copy(\n      activeLowestColor = Color(0xff212f57),\n      activeHighestColor = Color(0xff456de3),\n    ),\n    heatShape = CircleShape,\n  ),\n  startFromEnd = false\n)\n```\n\n### Interactivity\n\nNot just present, but interact.\n\n- Click\n- Scroll\n- Reaching the top or pulling back at the end\n\n### Generic data support\n\nThe operation is richer.\n\n```kotlin\n// ../library/src/commonMain/kotlin/com/fleeys/heatmap/HeatMap.kt\n\nimport kotlinx.datetime.LocalDate\n\ndata class Heat\u003cT\u003e(\n  val date: LocalDate,\n  var value: Double,\n  var data: T? = null\n)\n```\n\n## Supportive\n\nThis project is built on Compose in an attempt to adapt to the Compose Multiplatform.\n\nThe currently adapted platforms are listed below:\n\n| Platform |      State       |                            Sample                            | Note |\n| :------: | :--------------: | :----------------------------------------------------------: | :--: |\n| Android  |        ✅         | [Android-Sample](./sample/src/androidMain/kotlin/com/fleeys/heatmap/sample/MainActivity.kt) |      |\n| Desktop  |        ✅         | [Desktop-Sample](./sample/src/desktopMain/kotlin/com/fleeys/heatmap/sample/Main.kt) |      |\n|  WasmJs  | :expressionless: |                             ...                              | (1)  |\n\n1. Unfortunately, due to the fact that I don't know much about it, the realization is less than ideal. If you can help me refine it, quite welcome to contribute!\n\n## Contribution\n\nFeel free to submit an issue if you have any feedback or suggestions!\n\nThe project is quite happy to receive your contributions, and it will be much more robust with your help!\n\nI hope you like it, and if you think it's good, feel free to give a :star: !\n\n## License\n\n```\nCopyright (c) 2024-present. Fleey\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fifleey%2Fcompose-heatmap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fifleey%2Fcompose-heatmap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fifleey%2Fcompose-heatmap/lists"}