Lightweight Objective-C line and bar charts with configurable range, layout, tap interaction, and replayable entry animation.
Real screenshots from the generated pure-code demo on the current iPhone simulator:
- Pure Objective-C, UIKit based.
- Supports line charts and grouped/single bar charts.
- Multi-series comparison through one datasource abstraction.
- Configurable visible range, number of levels, and row width.
- Tap callbacks can drive custom animations or
UIMenuControllervalues. - Entry animation timing is controlled by each
XYChartItem.duration. - Demo is now pure code only and generated from
XcodeGen + CocoaPods.
pod 'XYChart'Requirements:
- iOS 12.0+ for the pod
- CocoaPods
XYChart/: pod core sourceDemo/Sources/: pure-code demo logicDemo/project.yml: XcodeGen definition for the demo appDemo/Podfile: CocoaPods integration for the demo appdocs/images/: README preview screenshotsGenerateDemo.command: one-click bootstrap script for the demo
One-click:
./GenerateDemo.commandManual:
brew install xcodegen cocoapods
cd Demo
xcodegen generate
pod install
open XYChartDemo.xcworkspaceNotes:
- Open
XYChartDemo.xcworkspace, not the generated.xcodeproj. - Generated files such as
Pods/,.xcworkspace, and.xcodeprojare not part of the repo core. - If you change
Demo/project.ymlorDemo/Podfile, rerunxcodegen generateandpod install. - The demo app itself targets iOS 13.0 because it uses modern scene lifecycle and current iPhone layout APIs.
#import <XYChart/XYChart.h>
#import <XYChart/XYChartItem.h>
#import <XYChart/XYChartDataSourceItem.h>
XYChartItem *lineA1 = [XYChartItem new];
lineA1.value = @28;
lineA1.color = UIColor.systemBlueColor;
lineA1.duration = 0.22;
lineA1.showName = @"Engagement | Mon | 28%";
XYChartItem *lineA2 = [XYChartItem new];
lineA2.value = @34;
lineA2.color = UIColor.systemBlueColor;
lineA2.duration = 0.22;
lineA2.showName = @"Engagement | Tue | 34%";
XYChartItem *lineB1 = [XYChartItem new];
lineB1.value = @19;
lineB1.color = UIColor.systemTealColor;
lineB1.duration = 0.25;
lineB1.showName = @"Conversion | Mon | 19%";
XYChartItem *lineB2 = [XYChartItem new];
lineB2.value = @26;
lineB2.color = UIColor.systemTealColor;
lineB2.duration = 0.25;
lineB2.showName = @"Conversion | Tue | 26%";
XYChartDataSourceItem *dataSource = [[XYChartDataSourceItem alloc] initWithDataList:@[
@[lineA1, lineA2],
@[lineB1, lineB2]
]];
dataSource.configuration.numberOfLevels = 5;
dataSource.configuration.autoSizingRowWidth = YES;
dataSource.configuration.automaticallyAdjustsVisibleRange = YES;
XYChart *chartView = [[XYChart alloc] initWithType:XYChartTypeLine];
chartView.delegate = self;
[chartView setDataSource:dataSource animation:YES];
[self.view addSubview:chartView];@interface XYChart : UIView<XYChartReload>
@property (nonatomic, weak, nullable) id<XYChartDataSource> dataSource;
@property (nonatomic, weak, nullable) id<XYChartDelegate> delegate;
@property (nonatomic, copy, nullable) XYChartConfiguration *configuration;
@property (nonatomic, readonly) XYChartType type;
- (instancetype)initWithFrame:(CGRect)frame type:(XYChartType)type;
- (instancetype)initWithType:(XYChartType)type;
- (void)setDataSource:(id<XYChartDataSource>)dataSource animation:(BOOL)animation;
- (void)reloadData:(BOOL)animation;
@endXYChartConfiguration *configuration = [XYChartConfiguration defaultConfiguration];
configuration.visibleRange = XYRangeMake(0, 100);
configuration.automaticallyAdjustsVisibleRange = YES;
configuration.numberOfLevels = 6;
configuration.autoSizingRowWidth = NO;
configuration.rowWidth = 52.0;Available properties:
visibleRangeautomaticallyAdjustsVisibleRangenumberOfLevelsrowWidthautoSizingRowWidth
XYChartItem *item = [XYChartItem new];
item.value = @42;
item.color = UIColor.systemBlueColor;
item.duration = 0.22;
item.showName = @"North | Jan | 42k";Notes:
durationcontrols line draw speed, point reveal timing, and bar grow timing.showNameis used byUIMenuControllerwhen menu display is enabled.
Required methods:
- (NSUInteger)numberOfSectionsInChart:(XYChart *)chart;
- (NSUInteger)numberOfRowsInChart:(XYChart *)chart;
- (NSAttributedString *)chart:(XYChart *)chart titleOfRowAtIndex:(NSUInteger)index;
- (id<XYChartItem>)chart:(XYChart *)chart itemOfIndex:(NSIndexPath *)index;Optional methods:
- (nullable XYChartConfiguration *)chartConfiguration:(XYChart *)chart;
- (NSAttributedString *)chart:(XYChart *)chart titleOfSectionAtValue:(CGFloat)sectionValue;
- (BOOL)autoSizingRowInChart:(XYChart *)chart;
- (CGFloat)rowWidthOfChart:(XYChart *)chart;
- (NSUInteger)numberOfLevelInChart:(XYChart *)chart;
- (XYRange)visibleRangeInChart:(XYChart *)chart;- (BOOL)chart:(XYChart *)chart shouldShowMenu:(NSIndexPath *)index;
- (void)chart:(XYChart *)chart itemDidClick:(id<XYChartItem>)item;
- (CAAnimation *)chart:(XYChart *)chart clickAnimationOfIndex:(NSIndexPath *)index;Typical uses:
- decide whether a tapped point or bar should show
UIMenuController - update footer text or external labels when the user taps a value
- provide custom tap feedback animations per chart or per index
The current demo app includes:
- 3 line cases
- 3 bar cases
- replay button per card
UIMenuControllervalue display- sequential line draw and bar grow animation
- pure-code layout that supports current iPhone safe areas and screen sizes
- The demo app uses
UIScenelifecycle and a pure-codeSceneDelegate. - The generated demo project is intentionally disposable; edit source and config, then regenerate.
- For local verification:
cd Demo
xcodegen generate
pod install
xcodebuild -workspace XYChartDemo.xcworkspace -scheme XYChartDemo -configuration Debug -destination 'generic/platform=iOS Simulator' buildXcodeYang, xcodeyang@gmail.com
XYChart is available under the MIT license. See LICENSE.

