MPAndroidChart 4.0.0
MPAndroidChart 4.0 is here: the library rewritten from the ground up in Kotlin, with a Jetpack Compose module. It is the first stable release since 3.1.0.
📖 Guides and documentation: philjay.cc/mpandroidchart · 35 chapters from a first chart to theming, Compose, custom renderers and troubleshooting.
- Kotlin first. Properties instead of getter and setter pairs, lambdas for formatters and listeners (
chart.onValueSelected { entry, highlight -> }), typed entry payloads, lists instead of arrays. Java callers keep working. - Jetpack Compose. The new
MPChartComposemodule: a composable for every chart type,ChartStateto read and drive a chart, and markers written as composables. - Animated data changes.
animateDataChange(newData)moves every value smoothly to its new one, andanimateValue(entry, toY)animates a single value. Every animation takes anonEndcallback, andisAnimatingandstopAnimations()are new. In Compose,animateChanges = trueanimates new data automatically. - Empty and loading states. A modern empty state with an outline of the chart type instead of the old yellow text, and
isLoadingfor data that is still on its way. Everything about it can be customized. - New styling. Rounded bars and stacked sections, rounded radar corners, a ring around the highlighted point, and highlight lines that can stop at the entry.
- Robust. Tested against NaN, Infinity, empty data and 100,000 entries, inside
RecyclerViewandLazyColumn, across rotation and with leak checks. More than 40 reported issues are fixed.
- Lines draw about 1.2x faster than in 3.1.0, and bars 1.6x faster with the new
isDecimationEnabled, which drops entries that share a pixel column. - A zoomed-in bar chart builds only the bars on screen: 2.5 ms per frame with 500 bars in view, whether the data holds 10,000 or 300,000.
- Line circles that would cover each other are skipped, and crowded candles are thinned out, so 100,000 entries draw in well under a second with default settings.
The performance chapter has all measurements.
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven("https://jitpack.io")
}
}
// build.gradle.kts
dependencies {
implementation("com.github.PhilJay.MPAndroidChart:MPChartLib:v4.0.0")
implementation("com.github.PhilJay.MPAndroidChart:MPChartCompose:v4.0.0") // only for Compose
}
minSdk 23 · compileSdk 35 (37 for Compose) · Java 17 · Kotlin 2.0 or newer. The getting started guide takes you from here to a first chart.
- From 3.x: class, package and interface names are unchanged, so imports survive and call sites change. The migration guide and MIGRATION.md cover every step. Projects on the 3.x coordinates keep building untouched.
- Staying on 3.x? Nothing changes for you. 3.2.0 is the last Java release with every fix from 3.x; coming from 3.1.0 it needs small formatter changes, which its notes list. The code lives on the
3.xbranch. - From 4.0.0-beta01: scatter shape sizes and
ComposeMarker.offsetare now in dp,centerTextSizePixelsis gone,PieData.dataSetis nullable andLargeValueFormatter.suffixis a list.
CHANGELOG.md lists every change. Thanks to everyone who reported issues and sent pull requests over the years.
Version 3.2.0
The last release of the Java 3.x line. It packages everything merged into master since 3.1.0 as a stable, pinned version.
implementation 'com.github.PhilJay:MPAndroidChart:v3.2.0'
Same coordinates as before, Java API, minSdk 14.
- On
master-SNAPSHOTor a recentmastercommit: yes, switch tov3.2.0now. It is exactly the code you use today, andmastermoves to the Kotlin rewrite with 4.0.0. - On 3.0.x: yes. The formatter API is the same as in 3.0.x, and you get the fixes and additions below.
- On 3.1.0: only if you are ready to adjust your formatters. 3.2.0 goes back to the formatter interfaces of 3.0.x, so code that extends
ValueFormatterno longer compiles (see below). Staying on 3.1.0 is fine, and 4.0.0 is the way forward.
ValueFormatteris gone. ImplementIValueFormatterfor values andIAxisValueFormatterfor axes instead, as in 3.0.x:xAxis.setValueFormatter((value, axis) -> "M" + (int) value); dataSet.setValueFormatter((value, entry, dataSetIndex, viewPortHandler) -> value + " kg");
PercentFormatter(PieChart)is replaced bynew PercentFormatter()together withpieChart.setUsePercentValues(true).- Gradients moved to bars.
setGradientColor(start, end)andsetGradientColors(...)now live onBarDataSet, wheresetGradientColorstakesFillobjects;getGradientColor()becomesgetFill(index). IPieDataSet.isUsingSliceColorAsValueLineColor()is nowisUseValueColorForLineEnabled().- Custom renderers:
drawValuereceives the formatter and entry again:drawValue(Canvas, IValueFormatter, value, entry, dataSetIndex, x, y, color).
Fillfor bar colors: solid colors, gradients and drawables, viaBarDataSet.setFills(...).GradientColorremains as a deprecated subclass ofFill.- Combined charts:
highlightValue(x, dataSetIndex, dataIndex)highlights an entry inside one of the combined data objects. - Pie charts:
PieDataSet.setHighlightColor(...), andsetUseValueColorForLine(true)to draw each value line in its slice color. - Axes:
setAxisMinLabels/setAxisMaxLabelsto change the allowed label count range, andYAxis.setLabelXOffset(...). - Drawing:
setClipDataToContent(false)lets data draw outside the content rectangle. - No data text:
setNoDataTextAlignment(...)aligns it left, center or right. - Data sets:
getEntries()/setEntries()replacegetValues()/setValues(), which stay as deprecated aliases. - Filtering:
ApproximatorN.reduceWithDouglasPeucker(points, resultCount)reduces a line to a target number of points.
- A crash with solid colors in bar charts (#4802).
- An index out of bounds crash in stacked bar charts.
- Axis labels that disappeared while zooming in, and a race around the label interval.
- A pie slice without highlight enabled was hidden when highlighted.
- An unexpected dashed line during linear line animations.
- Bubbles drawn with the color of the wrong entry, and the wrong axis used for legend spacing in horizontal bar charts.
- The axis dependency is now respected in combined charts, and horizontal bar charts get correct negative offsets.
onChartScaleis now called after a double tap zoom.- The legend height now includes its last line of labels.
- Clearing a data set now resets its min and max.
- The project builds with current Android Studio versions (#5456).
MPAndroidChart 4.0.0 follows right after this release: a complete rewrite in Kotlin with a Jetpack Compose module, new coordinates and extensive guides at philjay.cc/mpandroidchart. Projects on 3.x are not affected until they choose to migrate, and the migration guide walks through every step. The 3.x code stays available on the 3.x branch.
Thanks to everyone who contributed fixes and features to 3.x: @danielgindi, @oatrice, @duchampdev, @UrielFrankel, @nathan-fiscaletti and many others.
v3.9.0
Highlights
- Updates the Fresco source-build toolchain to Android Gradle Plugin 9.2.1, Gradle 9.4.1, and NDK r28c (
28.2.13676358) (d74afa8eb22518830776f75e2a864d83e421aecb) - Adds a
ProducerFactory.newBitmapMemoryCacheKeyMultiplexProduceroverload that accepts an explicitCacheKeyFactory, allowing delegated cache requests to be multiplexed with their own cache-key factory (c361d615c1200c46c1d8c0163cfae97d8221427e) - Adds exact-key removal for memory caches and introduces
UnifiedEncodedMemoryCache; Fresco's encoded-memory-cache producer now uses the shared cache boundary (745298f652d28ce219043977cdb9412af17d57ac, 53dc796565b8ad3902c8e2e304cadc0c47a175ba) - Generalizes
EncodedCountingMemoryCacheFactoryto create caches for custom encoded value types through aValueDescriptor(53dc796565b8ad3902c8e2e304cadc0c47a175ba) - Adds a Vito warning when a
CloseableBitmaphas a nullunderlyingBitmap, helping diagnose images that may already be closed (028280873e8bfc554d6fa776215927aedadf4bbc)
Source builds only:
- The repository moves from AGP 8.10.1, Gradle 8.11.1, and NDK r27b to AGP 9.2.1, Gradle 9.4.1, and NDK r28c. The build now relies on AGP 9's built-in Kotlin support instead of applying
kotlin-android, and annotation-processing modules usecom.android.legacy-kaptinstead ofkotlin-kapt. Source-build automation or patches that depend on the previous wrapper or plugin IDs must be updated (d74afa8eb22518830776f75e2a864d83e421aecb)
Full Changelog: https://github.com/facebook/fresco/compare/v3.8.0...v3.9.0
v3.8.0
Highlights
- Adds an encoded-image request transformation hook and makes disk-cache write producer creation overridable (58ac45fa33e37b9ac1521a9124b783a6144582d7)
- Adds
EncodedImageDimensionsDecoderand a registry for custom image-dimension decoding (b0742d60175f8dc799169daf01ebff673ad101fc) - Adds
MultiPostprocessorfor applying multiple postprocessors in sequence (ddc1db1f2707445e17fced4c303bd3bbd6a2b4fe) - Adds
EmptyImageSource.isExpectedEmptyso intentional empty Vito sources can retain their placeholders without reporting failures (0b0bc9dadb3835edcccec2c579a0d9e4ce0f55a5, d8380341736fdcc0e89e82b23e2adc2babfb3617) - Lets custom producer-sequence factories handle decoded HTTP(S) requests and encoded network prefetches (793dabcffca074797603aff5d0ac475191fef4ac, 6bcf6e3fb166bfdf8204a07a31cdad8da9dfea9c)
- Adds framework-neutral cache-key generation with
UnifiedCacheKeyGenerator(f650f5d18c5fc407200ef481a7ec803bbc8bc7b1) - Adds request creation from complete
SingleImageSourceinstances and request-based cache eviction that honors custom cache keys (7bf53dff1cc146c2cd2681399ec0a4f8bbce1f53, 8366d2701fa71b674704f3e53aad76afb49caeed) - Adds opt-in streaming image decoding with byte- and time-based partial-result throttling (9e2b4595ad1d8f228c36c5fba993b270efe6133a, f2d88bbb48552450fe368c3f2e2846fd4272ffcd)
- Adds an option to keep the progress indicator visible while intermediate Vito images are displayed (624a167075555f63b38e3a1f72cf9ade74fb9d56)
- Exposes the configured memory-chunk pool through
PoolFactory.getMemoryChunkPool(06140ac8a11678cec7aea4d0262505fbd42a1e2a) - Adds
PrefetchDataand prefetch telemetry plumbing (936699641f3cf8b306eaa62265724e0d8aefc0ed) - Reduces final-image latency by letting completed decode results bypass the progressive-decode interval (02414e429ec1df1c3a2a633f6e206d8361034c85, e0ecb758083bcfcc3e19aadc41780a7b3333dca9)
- Supports building the OkHttp backend against both OkHttp 3.x and 4.x (288a34c60a35d2d99912d43e2b6559af1e3fa61e, bc35d331f1646dcb00b7876e4daa9b48055e5413)
- Fixes an Android 16 null dereference when creating the default Vito drawable factory (7b7b29a3b325126c538b044d1d7afc49cc4c53f1)
- Hardens native WebP decoding against invalid dimensions, oversized canvases, negative lengths, and unsafe byte-array ranges (a160b3b1bbfb3f4032bd2efc423e37f637be215b, 1566dd8f87a637907cc42cf13a5faefa8f46ea90)
- Fixes recycled-bitmap rendering in Vito (41905be2a1cdf43a466a2623ae48165bdc25eb04)
- Fixes races and invalid-dimension handling in on-demand animations (762ed58dcf6f97f71cf4fabc820e06ea210bb880, b57c87456345409ee144def24da82667a6aaa30f)
- Fixes concurrency-related null dereferences in request listeners and Vito image tracking (2baa5d40651f8881f5982fd6ab11789baeac32d9, c6620d772e0e4fad72429a0db986508bb3a30bb6)
- Fixes source builds with JDK 25 and aligns the OSS Gradle build with Kotlin 2.2 (288cdbb6870c7ffd2f6ff9ae714c9fbd63524383, c90d7f069174259d6d4567e04dd9f78b07dc1c8c, 0209f2496f362d2380437f1e3a6ef220fe76410b, 15df97e435f104f80b6ab8cabdc614e1b39d63de)
Method signature changes:
- Changes
ProducerFactory.newDiskCacheWriteProducerto returnProducer<EncodedImage>instead ofDiskCacheWriteProducer(58ac45fa33e37b9ac1521a9124b783a6144582d7)
Removed classes and options:
- Removes
EfficientPlatformDecoder,EfficientRawBitmapDecoder,DecodeValidationUtils, and thePlatformDecoderOptions.useEfficientDecoderanduseBitmapFactoryDecoderoptions (d7ed19ab1705c63d4bed185d0efb990cb3f9833f, 5bc48b675f5cc3715d71ccd1009d03447df54f8c, d4f73938ace28184415aed5bdda915901aac2e5d)
Kotlin migration changes:
- Makes
MatrixDrawableandRoundedBitmapDrawablefinal and makes several previously overridableFadeDrawablemethods final (f60d58d71149ab007be7d76d5b9c0fada650dfc2, dc82282e214b331d24b926ae6965f3a982a1cff7, 9926a960d86d3ad6097ca2ef362e0b8518690ac1) - Makes
StreamUtilandUriUtilsingletons; their static operations remain available, but construction and subclassing are no longer supported (e708aed9aa6f6d440a18b62d838a423d44283d77, 5f2b04b83d93833dd302322b50aeca40bd845b73) - Makes
NativeJpegTranscoderFactoryfinal andNativeJpegTranscoderSoLoadera singleton (f69ccbc66bafe6b64b6301142ca0f5739e1c7a0f) - Changes selected Kotlin getter calls on
FrameScheduler,GifFrame, andWebPFrameto property access (d30727c402a6f9c5b8e03add5ced46abb80484de, 0f7acde029049f8e5864dbba2fef66fab501301b, 0266179cb9bfe420d8d434043c0989f3e43cf61a)
Behavioral changes:
- Cache-only decode misses now report errors;
cancelDecodeOnCacheMissno longer changes this behavior (0e7644ef410164bb7a3d2b8d2f28c6af3d50ff0f, 762ed58dcf6f97f71cf4fabc820e06ea210bb880)
Full Changelog: https://github.com/facebook/fresco/compare/v3.7.0...v3.8.0
0.88.0-rc.2
- Metro: Bump the minimum Metro version to 0.87.1, so upgrading projects resolve the same Metro as freshly created ones (f2439a83cf by @robhogan)
- TurboModules: Revert the
RCTArrayBuffercodegen change, restoringNSMutableData *for ObjC TurboModule methods that take or return anArrayBuffer. 0.88 is a non-breaking release, and the change stopped modules that adopted ObjCArrayBuffersupport in 0.87 from compiling (639cdedb50, 19a3184981 by @fabriziocucci) - TurboModules: Revert the rejection of
ArrayBufferas a TurboModuleEventEmitterpayload. C++ TurboModules could declareEventEmitter<ArrayBuffer>in 0.87 and it generated working code, so rejecting it at codegen time broke those builds (070af03ab3 by @fabriziocucci) - TypeScript: Restore the
.jsfallback for legacy deep imports of untyped modules, soreact-native/Libraries/*specifiers resolve again under thereact-native-legacy-deep-importscondition (579212e15c by @fabriziocucci)
Hermes V1 dSYMS:
ReactNativeDependencies dSYMs:
ReactNative Core dSYMs:
You can file issues or pick requests against this release here.
To help you upgrade to this version, you can use the Upgrade Helper ⚛️.
View the whole changelog in the CHANGELOG.md file.
4.2.1-alpha02
- Added gradient support for dashed and dot-dashed drawing lines
- Added a unified shuffle button for seed selectors
- Added ability to use plus minus buttons in value dialogs
- Added ability to import generative inpainting AI model by #3166
- Added undo redo option to 3 tools
- Added more flexibility to gradient paints
- Fixed style transfer models maximum resolution by #3160
- Fixed blur edges saving in profiles by #3161
- Fixed crash with multiple custom fonts by #3162
- Improved UI
Full Changelog: https://github.com/T8RIN/ImageToolbox/compare/4.2.1-alpha01...4.2.1-alpha02
4.0.0-beta01
MPAndroidChart is back, rewritten from the ground up in Kotlin, with a Jetpack Compose module and documentation to match.
A Kotlin API that feels like Kotlin. Every getter and setter pair is a property, boolean flags read isXxxEnabled, and formatters and listeners are functional interfaces, so a lambda is enough: chart.onValueSelected { entry, highlight -> }. Colors, labels and draw orders are lists instead of arrays, entries carry a typed payload, and notifyDataSetChanged() alone recalculates and redraws.
Jetpack Compose. A new MPChartCompose module: one composable per chart type, ChartState for reading and driving a chart from Compose, and ComposeMarker for markers written as composables.
Faster with large data. Bars are clipped to the viewport, points are reduced to what a pixel column can actually show, entry lookup goes through the x value instead of walking the set, and the shared object pools no longer grow on every frame.
New styling. Rounded bars and rounded corners on every section of a stacked bar, rounded polygon corners on radar charts, a ring and halo around the highlighted point of a line chart, and highlight lines that can stop at the entry instead of crossing the whole chart.
Sharper axes and labels. X axis labels keep a label's width apart instead of overlapping, value labels are decided per data set from what is actually in view, and forced labels respect the axis granularity.
More than 40 reported issues fixed, plus six community pull requests ported. CHANGELOG.md has the full list.
Documentation. 35 chapters of guides at philjay.cc/mpandroidchart/docs, KDoc on every public class, function and property, and a generated API reference for MPChartLib and MPChartCompose.
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven("https://jitpack.io")
}
}
// build.gradle.kts
dependencies {
implementation("com.github.PhilJay.MPAndroidChart:MPChartLib:v4.0.0-beta01")
implementation("com.github.PhilJay.MPAndroidChart:MPChartCompose:v4.0.0-beta01") // only for Compose
}
minSdk 23, compileSdk 35, Java 17 and Kotlin 2.0 or newer. Java callers need no Kotlin at all. The Compose module needs compileSdk 37, because Compose itself does.
The class, package and interface names are unchanged, so imports survive and the call sites change. MIGRATION.md lists every change with before and after code, and the migration guide walks through them.
Nothing here disturbs an existing project: 4.0 publishes under a new coordinate, so com.github.PhilJay:MPAndroidChart:v3.1.0 keeps resolving exactly as it does today, and master still carries the 3.x sources.
The API can still change before 4.0.0, so pin this version rather than tracking the newest one. Feedback and bug reports are very welcome.
4.2.1-alpha01
- Added ability to use gradient instead of solid color to draw and markup layers tool
- Added recent and favorites to gradient palettes editor
- Added ability to use gradient backgrounds in collages and image stitching
- Added 38 filters and 43 textures
- Added 2 new filter groups: Glitch, Geometry
- Replaced jUnrar with libarchive in FOSS build by #3121 #3124
- Fixed UI of template manager by #3122
- Fixed OOM after language changing by #3125
- Fixed CRT filter crash in preview by #3140
- Fixed style transfer models in AI tools by #3144
- Fixed OOM in compression lab and resize by weight by #3142
- Fixed timestamp adding to filename by #3147
Full Changelog: https://github.com/T8RIN/ImageToolbox/compare/4.2.0...4.2.1-alpha01
v.3.1.1 - Text Selection Position
- Use Ubuntu for UI tests triggered by GitHub Actions by @wasky in https://github.com/burhanrashid52/PhotoEditor/pull/554
- Fix clearing redo stack after brush drawing by @wasky in https://github.com/burhanrashid52/PhotoEditor/pull/553
- Bump versionCode for the new release by @licaon-kter in https://github.com/burhanrashid52/PhotoEditor/pull/557
- Feature/bump by @benju69 in https://github.com/burhanrashid52/PhotoEditor/pull/559
- Undo redo buttons disabled state by @wasky in https://github.com/burhanrashid52/PhotoEditor/pull/555
- Clean code by @benju69 in https://github.com/burhanrashid52/PhotoEditor/pull/560
- v.3.1.0 Release release changes by @burhanrashid52 in https://github.com/burhanrashid52/PhotoEditor/pull/561
- Revert "v.3.1.0 Release release changes" by @burhanrashid52 in https://github.com/burhanrashid52/PhotoEditor/pull/562
- "setBrushEraserSize" size is not working as expected by @daniel-costaa in https://github.com/burhanrashid52/PhotoEditor/pull/564
- Add shapePaintStyle to ShapeBuilder by @stephanepechard in https://github.com/burhanrashid52/PhotoEditor/pull/586
- Draw a uniform filled shape on a single tap by @stephanepechard in https://github.com/burhanrashid52/PhotoEditor/pull/591
- Add tap-to-place text positioning by @boardtc in https://github.com/burhanrashid52/PhotoEditor/pull/592
- Unify PhotoEditor.addText API for Kotlin default parameters by @boardtc in https://github.com/burhanrashid52/PhotoEditor/pull/595
- @licaon-kter made their first contribution in https://github.com/burhanrashid52/PhotoEditor/pull/557
- @benju69 made their first contribution in https://github.com/burhanrashid52/PhotoEditor/pull/559
- @daniel-costaa made their first contribution in https://github.com/burhanrashid52/PhotoEditor/pull/564
- @boardtc made their first contribution in https://github.com/burhanrashid52/PhotoEditor/pull/592
Full Changelog: https://github.com/burhanrashid52/PhotoEditor/compare/v.3.0.2...v.3.1.1
0.88.0-rc.1
- EventTarget: Enable the imperative EventTarget API (
addEventListener,removeEventListener,dispatchEvent) on native view refs in canary (8480b86820 by @rubennorte)
- Events: Enabled Web-based event dispatching refactor (31d33ce91b by @rubennorte)
- Hermes: Bump Hermes to 260318099.0.3 (79024f7c59 by @fabriziocucci)
- React: Sync React 19.3.0 into React Native (b0b71421c1 by @rubennorte)
- Codegen: No longer crawls
node_modulesor follows symlinks when discovering components (39751d864d by @gabrieldonadel) - SwiftPM: Generated manifests derive their iOS platform floor from the app's
IPHONEOS_DEPLOYMENT_TARGETinstead of hardcoding iOS 15, so dependencies with a higher minimum (e.g. Expo, 16.4) can be autolinked (92564f33fd by @chrfalch) - SwiftPM: Read the SwiftPM name from the podspec and store it in package.json when scaffolding (1cfc5f29a0 by @chrfalch)
- SwiftPM: Run generated build scripts under bash instead of /bin/sh, so they don't break on a host where /bin/sh isn't bash (25f48bd72f by @lazerg)
Hermes V1 dSYMS:
ReactNativeDependencies dSYMs:
ReactNative Core dSYMs:
You can file issues or pick requests against this release here.
To help you upgrade to this version, you can use the Upgrade Helper ⚛️.
View the whole changelog in the CHANGELOG.md file.