CLI tool
ZhipingYang/XYChart avatar
ZhipingYang/XYChart

XYChart and the case for a chart you draw yourself in Objective-C

XYChart is designed for line & bar of charts which can compare mutiple datas in form styles, and limited the range of values to show, and so on.

707 stars167 forksObjective-CApache-2.0

At a glance

What is it?
XYChart is a small UIKit library for line and bar charts where each row of data is a series, the visible value range is configurable, and the entry animation is timed per item. Its appeal is control over the drawing, and its limits are that it is one author, one platform, and no Swift example.
Who is it for?
XYChart suits an iOS team in Objective-C that wants a chart it can fully control, from the visible value range to the per-point animation timing, and that needs the same widget to render a line series and a bar series without maintaining two code paths. It does not suit a Swift project expecting Swift-first APIs and documentation, and it does not suit anyone who needs axis labelling, legends or accessibility behaviour that the project does not implement.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Objective-C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Rows are series, not categories

The one design decision that explains the whole API is that a row of data is a series and a section is a category.

The data source protocol requires the number of sections in the chart and the number of rows in the chart, plus a title for each row and an item for each index path. So a chart with three sections and two rows draws two lines, one per row, with three points each. The quick start example makes that concrete: two arrays of two items each are passed to the data source, one array of two blue items named for engagement on Monday and Tuesday, the other of two teal items named for conversion on the same days, and the whole thing becomes one line chart with two series.

That is worth pausing on, because it is the opposite of the usual chart convention. In a typical charting library a series is a colour and a category is a point on the x axis, so multiple series are compared across categories. Here the rows are the series and the sections are the categories, which is why the title is fetched per row rather than per section, and why the row title method and the section title method sit at different levels of the protocol.

The bar chart is grouped the same way, so a grouped bar chart is the same data structure rendered differently rather than a separate model.

The visible range is a first-class configuration

The second thing the library is built around is that you decide what part of the data is on screen.

The configuration exposes a visibleRange, made with XYRangeMake, and a separate automaticallyAdjustsVisibleRange flag. The quick start turns automatic adjustment on, and the configuration API reference shows the pair being set in the other direction, with a range of zero to a hundred and automatic adjustment enabled as well, which is a configuration you would tune rather than leave alone.

Alongside the range there are numberOfLevels, the number of grid levels, and rowWidth with a companion autoSizingRowWidth flag, where the sample sets autoSizingRowWidth to no and the width to 52 points.

The optional data source methods mirror this design. A data source can override the configuration, the row width, the number of levels and the visible range, so the chart view can be configured once and still have per-chart overrides, or the overrides can be decided per chart by the data source itself. The autoSizingRowInChart and rowWidthOfChart methods are where a row width computed from content rather than fixed points would go.

For a dashboard that shows several charts side by side, this is the part that makes the library usable, because it is what lets a small chart and a large chart show the same data honestly.

Animation timing lives on the data item

Each item carries a duration, and the documentation is explicit that it controls line draw speed, point reveal timing and bar grow timing.

That is a small property with a large effect. The quick start gives the two engagement items a duration of 0.22 and the two conversion items 0.25, so a two-series chart draws in a staggered order rather than all at once, and each series takes a different amount of time to appear.

The demo coverage list confirms the intent: sequential line draw and bar grow animation, plus a replay button per card, so the entry animation can be watched over and over rather than being seen once and lost.

The chart view also has a reloadData method that takes an animation flag, and setDataSource takes one too, so the same animation machinery serves both the initial load and a data refresh.

The point of putting duration on the item rather than on the configuration is that it makes the timing part of the data. If two series should be revealed at different speeds, that is expressed where the data is defined rather than in a global setting that applies to everything.

Taps, menus and custom animations come back through the delegate

The delegate protocol is small and its three methods map onto three different things you might want to do on a tap.

There is a shouldShowMenu method, which decides whether a tapped point or bar should show a UIMenuController, a chart:itemDidClick: method, and a chart:clickAnimationOfIndex: method that returns a CAAnimation so you can provide custom tap feedback per chart or per index.

The documented uses of those are worth quoting in spirit because they show the intended level of ambition. You can decide whether a tapped point should show a menu, you can update footer text or external labels when the user taps a value, and you can supply your own animation. The item carries a showName string, and the documentation notes that showName is used by the UIMenuController when menu display is enabled, so the value that appears in the menu comes from the data item.

The quick start sets showName to a formatted string such as "Engagement | Mon | 28%", which is a pipe-separated label. Combining a custom name and a delegate that decides to show the menu is how you turn a chart into a small interactive readout without building a separate legend.

The delegate is declared weak, as is the data source, and the chart is a UIView subclass, so it drops into any layout.

The demo is generated, and the generated parts are disposable

The repository is unusual in a way worth reading before you try to build it, because the demo project is not checked in.

The demo is pure code only and generated from XcodeGen plus CocoaPods, and the demo files at the top level are a Podfile, a Podfile.lock, a Sources directory and a project.yml. There is a one-click bootstrap script, GenerateDemo.command.

The one-click route is:

bash
./GenerateDemo.command

And the manual route installs the two tools, generates the project, installs the pods and opens the workspace:

bash
brew install xcodegen cocoapods
cd Demo
xcodegen generate
pod install
open XYChartDemo.xcworkspace

The notes carry three warnings that save time. Open the workspace, not the generated project file. Generated files such as Pods, the workspace and the project are not part of the repository core. And if you change project.yml or the Podfile you rerun xcodegen generate and pod install.

The development notes put the philosophy plainly: the generated demo project is intentionally disposable, so you edit source and config and then regenerate. That is a reasonable choice for a project where the demo is the documentation, and it means the demo is always in step with the current toolchain rather than rotting at the version it was written against.

For local verification the project documents a command that builds the demo for the simulator.

A CocoaPods pod, an iOS 12 floor, and a licence question

Installing the library is one line in a Podfile:

ruby
pod 'XYChart'

The requirements are iOS 12.0 or newer for the pod, and CocoaPods. The pod spec is at the repository root as XYChart.podspec, and the pod core source is in the XYChart/ directory.

The deployment target for the library and the demo are different, and the project says so. The pod supports iOS 12.0 and newer, while the demo app itself targets iOS 13.0 because it uses the modern scene lifecycle and current iPhone layout APIs. So the library is usable in an older app even though its own demo is not.

The licence needs a note, because the project description disagrees with the source. The recorded licence identifier is Apache-2.0, while the project guide states that XYChart is available under the MIT license and points at the LICENSE file. Anyone taking this into a commercial app should read the LICENSE file itself and settle the question with the author rather than relying on either of the two statements.

The author is XcodeYang. The last push to the repository was on 2026-04-07, and the project publishes no GitHub releases, so there is no versioned artefact beyond what CocoaPods resolves.

Where XYChart stops being the right answer

Three boundaries are worth stating.

The first is the platform and the language. The library is pure Objective-C and UIKit based, with no Swift example anywhere in the documentation. That is fine in a mature Objective-C codebase, and it is friction in a new Swift one, where the bridging header and the interop story become part of the work.

The second is the absence of features the project does not claim. There is no axis labelling, no legend component, no documentation of accessibility behaviour for the chart content, and no mention of VoiceOver support. The configuration covers the visible range, the number of levels and the row width, and that is the extent of the layout control. If your chart needs labelled axes, you draw them yourself or you use something else.

The third is scale and longevity. This is one author, a repository with no releases, a last push in April 2026, and a pod that is a handful of files. It is a pleasant, small, focused library, and it will not have a compatibility matrix for future iOS versions unless the author keeps working on it.

The realistic fit is a specific kind of internal dashboard or settings screen where you need a couple of series compared and you want the drawing to look exactly like the rest of your app, rather than a general charting library for a consumer product.

Editorial conclusion

XYChart suits an iOS team in Objective-C that wants a chart it can fully control, from the visible value range to the per-point animation timing, and that needs the same widget to render a line series and a bar series without maintaining two code paths. It does not suit a Swift project expecting Swift-first APIs and documentation, and it does not suit anyone who needs axis labelling, legends or accessibility behaviour that the project does not implement. Before you adopt it, read the data source protocol rather than the chart view, because the chart is a renderer and the data source contract is where you actually write your code, and note that the last push was on 2026-04-07 with the project publishing no GitHub releases.

Frequently asked questions

What is XYChart?

It is a lightweight Objective-C, UIKit based library for line charts and grouped or single bar charts in iOS apps. It supports multi-series comparison through a single data source abstraction, a configurable visible range, number of levels and row width, tap callbacks, and a replayable entry animation.

How do I install XYChart?

Add the pod to your Podfile with pod 'XYChart'. The requirements are CocoaPods and iOS 12.0 or newer for the pod, although the demo app itself targets iOS 13.0 because it uses the modern scene lifecycle and current iPhone layout APIs.

How do I run the XYChart demo app?

Run ./GenerateDemo.command for the one-click route, or install xcodegen and cocoapods, change into the Demo directory, run xcodegen generate and pod install, then open XYChartDemo.xcworkspace rather than the generated project file. The generated project is intentionally disposable.

How does XYChart control the entry animation?

Each item carries a duration property, and it controls line draw speed, point reveal timing and bar grow timing. The demo shows a replay button per card so the animation can be watched repeatedly, and the chart view has reloadData and setDataSource methods that both take an animation flag.

What licence is XYChart released under?

The project guide states that XYChart is available under the MIT license and points at the LICENSE file, while the repository licence identifier is recorded as Apache-2.0. Read the LICENSE file in the repository to settle the difference before using it in a commercial app.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. ZhipingYang/XYChart on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zhipingyang-xychart.svg)](https://hysenlabs.com/projects/zhipingyang-xychart)

Was this useful?