Commit 64179264 authored by xuanthinh's avatar xuanthinh

Chart

parents
This source diff could not be displayed because it is too large. You can view the blob instead.
# How to contribute
Bug-fixes and features often come from users of the Charts framework, and improving it greatly. We want to keep it as easy as possible to contribute changes that improve the experience for users all around the world. There are a few guidelines that we
need contributors to follow so that we can have a chance of keeping on
top of things.
## Simple issues and bug reports
If you are reporting a bug which can be observed visually, please add to your issue either:
* Screenshots, if the bug is easily explainable
* A working sample project that we can compile, run, and immediately observe the issue
## Getting Started with Contributions
* Make sure you have a [GitHub account](https://github.com/signup/free)
* Submit a ticket for your issue, assuming one does not already exist.
* Clearly describe the issue including steps to reproduce when it is a bug.
* Make sure you fill in the earliest version (or commit number) that you know has the issue.
* Fork the repository on GitHub
## Making Changes
* Create a topic branch from where you want to base your work. This is usually the master branch.
* Make commits of logical units.
* Make sure your code conforms to the code style around it. It's easy, just look around!
* If you have made changes back and forth, or have made merges, your commit history might look messy and hard to understand. A single issue or change should still be in one commit. So please squash those commits together and rebase them however you need to - to make our lives easier when reading it later.
* Check for unnecessary whitespace with `git diff --check` before committing.
* Make sure your commit messages are in the proper format.
````
First line must be up to 50 chars (Fixes #1234)
The first line should be a short statement as to what have changed, and should also include an issue number, prefixed with a hash.
The body of the message comes after an empty new line, and describes the changes
more thoroughly, especially if there was a special case handled there,
or maybe some trickery that only code wizards can understand.
````
* Make sure you have tested your changes well.
* If your changes could theoretically affect some other component or case, which you do not necessarily use, you still have to test it.
* Create a Pull Request from your topic branch to the relevant branch in the main repo. If you go to the main repo of the framework, you'll see a big green button which pretty much prepares the PR for you. You just have to hit it.
## Making Trivial Changes
For changes of a trivial nature to comments and documentation, it is not
always necessary to create a new ticket. In this case, it is
appropriate to start the first line of a commit with '(doc)' instead of
a ticket number. Even the default commit message the GitHub generates is fine with us.
Pod::Spec.new do |s|
s.name = "Charts"
s.version = "4.1.0"
s.summary = "Charts is a powerful & easy to use chart library for iOS, tvOS and OSX (and Android)"
s.homepage = "https://github.com/danielgindi/Charts"
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" }
s.authors = "Daniel Cohen Gindi", "Philipp Jahoda"
s.ios.deployment_target = "12.0"
s.tvos.deployment_target = "12.0"
s.osx.deployment_target = "10.13"
s.source = { :git => "https://github.com/danielgindi/Charts.git", :tag => "v#{s.version}" }
s.default_subspec = "Core"
s.swift_version = '5.7'
s.cocoapods_version = '>= 1.5.0'
s.subspec "Core" do |ss|
ss.source_files = "Source/Charts/**/*.swift"
ss.dependency 'SwiftAlgorithms', '~> 1.0'
end
end
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A58A4ED274A941CA248EA921"
BuildableName = "Charts.framework"
BlueprintName = "Charts"
ReferencedContainer = "container:Charts.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2749BD5443C1CB5FE2080C2"
BuildableName = "ChartsTests.xctest"
BlueprintName = "ChartsTests"
ReferencedContainer = "container:Charts.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A58A4ED274A941CA248EA921"
BuildableName = "Charts.framework"
BlueprintName = "Charts"
ReferencedContainer = "container:Charts.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "FB_REFERENCE_IMAGE_DIR"
value = "$(SOURCE_ROOT)/Tests/ReferenceImages"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2749BD5443C1CB5FE2080C2"
BuildableName = "ChartsTests.xctest"
BlueprintName = "ChartsTests"
ReferencedContainer = "container:Charts.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2749BD5443C1CB5FE2080C2"
BuildableName = "ChartsTests.xctest"
BlueprintName = "ChartsTests"
ReferencedContainer = "container:Charts.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2749BD5443C1CB5FE2080C2"
BuildableName = "ChartsTests.xctest"
BlueprintName = "ChartsTests"
ReferencedContainer = "container:Charts.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "FB_REFERENCE_IMAGE_DIR"
value = "$(SOURCE_ROOT)/Tests/ReferenceImages"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Charts.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>ChartsTests.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "container:Charts.xcodeproj">
</FileRef>
<FileRef
location = "group:ChartsDemo-iOS/ChartsDemo-iOS.xcodeproj">
</FileRef>
<FileRef
location = "group:ChartsDemo-macOS/ChartsDemo-macOS.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
{
"pins" : [
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms",
"state" : {
"revision" : "b14b7f4c528c942f121c8b860b9410b2bf57825e",
"version" : "1.0.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
},
{
"identity" : "swift-snapshot-testing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-snapshot-testing",
"state" : {
"revision" : "f8a9c997c3c1dab4e216a8ec9014e23144cbab37",
"version" : "1.9.0"
}
}
],
"version" : 2
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>PlaygroundChart (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>5</integer>
</dict>
</dict>
</dict>
</plist>
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>ChartsDemo-iOS-Swift.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>ChartsDemo-iOS.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
</dict>
</dict>
</plist>
//
// AppDelegate.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
//
// AppDelegate.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "AppDelegate.h"
#import "DemoListViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
DemoListViewController *vc = [[DemoListViewController alloc] init];
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:vc];
if (@available(iOS 13.0, *)) {
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
[appearance configureWithOpaqueBackground];
nvc.navigationBar.standardAppearance = appearance;
nvc.navigationBar.scrollEdgeAppearance = appearance;
}
_window.rootViewController = nvc;
[_window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
//
// BalloonMarker.swift
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
import Foundation
import Charts
#if canImport(UIKit)
import UIKit
#endif
open class BalloonMarker: MarkerImage
{
@objc open var color: UIColor
@objc open var arrowSize = CGSize(width: 15, height: 11)
@objc open var font: UIFont
@objc open var textColor: UIColor
@objc open var insets: UIEdgeInsets
@objc open var minimumSize = CGSize()
fileprivate var label: String?
fileprivate var _labelSize: CGSize = CGSize()
fileprivate var _paragraphStyle: NSMutableParagraphStyle?
fileprivate var _drawAttributes = [NSAttributedString.Key : Any]()
@objc public init(color: UIColor, font: UIFont, textColor: UIColor, insets: UIEdgeInsets)
{
self.color = color
self.font = font
self.textColor = textColor
self.insets = insets
_paragraphStyle = NSParagraphStyle.default.mutableCopy() as? NSMutableParagraphStyle
_paragraphStyle?.alignment = .center
super.init()
}
open override func offsetForDrawing(atPoint point: CGPoint) -> CGPoint
{
var offset = self.offset
var size = self.size
if size.width == 0.0 && image != nil
{
size.width = image!.size.width
}
if size.height == 0.0 && image != nil
{
size.height = image!.size.height
}
let width = size.width
let height = size.height
let padding: CGFloat = 8.0
var origin = point
origin.x -= width / 2
origin.y -= height
if origin.x + offset.x < 0.0
{
offset.x = -origin.x + padding
}
else if let chart = chartView,
origin.x + width + offset.x > chart.bounds.size.width
{
offset.x = chart.bounds.size.width - origin.x - width - padding
}
if origin.y + offset.y < 0
{
offset.y = height + padding;
}
else if let chart = chartView,
origin.y + height + offset.y > chart.bounds.size.height
{
offset.y = chart.bounds.size.height - origin.y - height - padding
}
return offset
}
open override func draw(context: CGContext, point: CGPoint)
{
guard let label = label else { return }
let offset = self.offsetForDrawing(atPoint: point)
let size = self.size
var rect = CGRect(
origin: CGPoint(
x: point.x + offset.x,
y: point.y + offset.y),
size: size)
rect.origin.x -= size.width / 2.0
rect.origin.y -= size.height
context.saveGState()
context.setFillColor(color.cgColor)
if offset.y > 0
{
context.beginPath()
context.move(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y + arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x + (rect.size.width - arrowSize.width) / 2.0,
y: rect.origin.y + arrowSize.height))
//arrow vertex
context.addLine(to: CGPoint(
x: point.x,
y: point.y))
context.addLine(to: CGPoint(
x: rect.origin.x + (rect.size.width + arrowSize.width) / 2.0,
y: rect.origin.y + arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width,
y: rect.origin.y + arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width,
y: rect.origin.y + rect.size.height))
context.addLine(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y + rect.size.height))
context.addLine(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y + arrowSize.height))
context.fillPath()
}
else
{
context.beginPath()
context.move(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width,
y: rect.origin.y))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x + (rect.size.width + arrowSize.width) / 2.0,
y: rect.origin.y + rect.size.height - arrowSize.height))
//arrow vertex
context.addLine(to: CGPoint(
x: point.x,
y: point.y))
context.addLine(to: CGPoint(
x: rect.origin.x + (rect.size.width - arrowSize.width) / 2.0,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y))
context.fillPath()
}
if offset.y > 0 {
rect.origin.y += self.insets.top + arrowSize.height
} else {
rect.origin.y += self.insets.top
}
rect.size.height -= self.insets.top + self.insets.bottom
UIGraphicsPushContext(context)
label.draw(in: rect, withAttributes: _drawAttributes)
UIGraphicsPopContext()
context.restoreGState()
}
open override func refreshContent(entry: ChartDataEntry, highlight: Highlight)
{
setLabel(String(entry.y))
}
@objc open func setLabel(_ newLabel: String)
{
label = newLabel
_drawAttributes.removeAll()
_drawAttributes[.font] = self.font
_drawAttributes[.paragraphStyle] = _paragraphStyle
_drawAttributes[.foregroundColor] = self.textColor
_labelSize = label?.size(withAttributes: _drawAttributes) ?? CGSize.zero
var size = CGSize()
size.width = _labelSize.width + self.insets.left + self.insets.right
size.height = _labelSize.height + self.insets.top + self.insets.bottom
size.width = max(minimumSize.width, size.width)
size.height = max(minimumSize.height, size.height)
self.size = size
}
}
//
// RadarMarkerView.swift
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
import Foundation
import Charts
#if canImport(UIKit)
import UIKit
#endif
open class RadarMarkerView: MarkerView
{
@IBOutlet var label: UILabel?
open override func awakeFromNib()
{
self.offset.x = -self.frame.size.width / 2.0
self.offset.y = -self.frame.size.height - 7.0
}
open override func refreshContent(entry: ChartDataEntry, highlight: Highlight)
{
label?.text = String.init(format: "%d %%", Int(round(entry.y)))
layoutIfNeeded()
}
}
//
// XYMarkerView.swift
// ChartsDemo
// Copyright © 2016 dcg. All rights reserved.
//
import Foundation
import Charts
#if canImport(UIKit)
import UIKit
#endif
open class XYMarkerView: BalloonMarker
{
@objc open var xAxisValueFormatter: AxisValueFormatter?
fileprivate var yFormatter = NumberFormatter()
@objc public init(color: UIColor, font: UIFont, textColor: UIColor, insets: UIEdgeInsets,
xAxisValueFormatter: AxisValueFormatter)
{
super.init(color: color, font: font, textColor: textColor, insets: insets)
self.xAxisValueFormatter = xAxisValueFormatter
yFormatter.minimumFractionDigits = 1
yFormatter.maximumFractionDigits = 1
}
open override func refreshContent(entry: ChartDataEntry, highlight: Highlight)
{
setLabel("x: " + xAxisValueFormatter!.stringForValue(entry.x, axis: nil) + ", y: " + yFormatter.string(from: NSNumber(floatLiteral: entry.y))!)
}
}
//
// DemoBaseViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "ChartsDemo_iOS-Swift.h"
@interface DemoBaseViewController : UIViewController
{
@protected
NSArray *parties;
}
@property (nonatomic, strong) IBOutlet UIButton *optionsButton;
@property (nonatomic, strong) IBOutlet NSArray *options;
@property (nonatomic, assign) BOOL shouldHideData;
- (void)handleOption:(NSString *)key forChartView:(ChartViewBase *)chartView;
- (void)updateChartData;
- (void)setupPieChartView:(PieChartView *)chartView;
- (void)setupRadarChartView:(RadarChartView *)chartView;
- (void)setupBarLineChartView:(BarLineChartViewBase *)chartView;
@end
This diff is collapsed.
//
// DemoListViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
@interface DemoListViewController : UIViewController
@end
//
// DemoListViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "DemoListViewController.h"
#import "LineChart1ViewController.h"
#import "LineChart2ViewController.h"
#import "BarChartViewController.h"
#import "HorizontalBarChartViewController.h"
#import "CombinedChartViewController.h"
#import "PieChartViewController.h"
#import "PiePolylineChartViewController.h"
#import "ScatterChartViewController.h"
#import "StackedBarChartViewController.h"
#import "NegativeStackedBarChartViewController.h"
#import "AnotherBarChartViewController.h"
#import "MultipleLinesChartViewController.h"
#import "MultipleBarChartViewController.h"
#import "CandleStickChartViewController.h"
#import "CubicLineChartViewController.h"
#import "RadarChartViewController.h"
#import "ColoredLineChartViewController.h"
#import "SinusBarChartViewController.h"
#import "PositiveNegativeBarChartViewController.h"
#import "BubbleChartViewController.h"
#import "LineChartTimeViewController.h"
#import "LineChartFilledViewController.h"
#import "HalfPieChartViewController.h"
@interface DemoListViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic, strong) NSArray *itemDefs;
@end
@implementation DemoListViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Charts Demonstration";
self.itemDefs = @[
@{
@"title": @"Line Chart",
@"subtitle": @"A simple demonstration of the linechart.",
@"class": LineChart1ViewController.class
},
@{
@"title": @"Line Chart (Dual YAxis)",
@"subtitle": @"Demonstration of the linechart with dual y-axis.",
@"class": LineChart2ViewController.class
},
@{
@"title": @"Bar Chart",
@"subtitle": @"A simple demonstration of the bar chart.",
@"class": BarChartViewController.class
},
@{
@"title": @"Horizontal Bar Chart",
@"subtitle": @"A simple demonstration of the horizontal bar chart.",
@"class": HorizontalBarChartViewController.class
},
@{
@"title": @"Combined Chart",
@"subtitle": @"Demonstrates how to create a combined chart (bar and line in this case).",
@"class": CombinedChartViewController.class
},
@{
@"title": @"Pie Chart",
@"subtitle": @"A simple demonstration of the pie chart.",
@"class": PieChartViewController.class
},
@{
@"title": @"Pie Chart with value lines",
@"subtitle": @"A simple demonstration of the pie chart with polyline notes.",
@"class": PiePolylineChartViewController.class
},
@{
@"title": @"Scatter Chart",
@"subtitle": @"A simple demonstration of the scatter chart.",
@"class": ScatterChartViewController.class
},
@{
@"title": @"Bubble Chart",
@"subtitle": @"A simple demonstration of the bubble chart.",
@"class": BubbleChartViewController.class
},
@{
@"title": @"Stacked Bar Chart",
@"subtitle": @"A simple demonstration of a bar chart with stacked bars.",
@"class": StackedBarChartViewController.class
},
@{
@"title": @"Stacked Bar Chart Negative",
@"subtitle": @"A simple demonstration of stacked bars with negative and positive values.",
@"class": NegativeStackedBarChartViewController.class
},
@{
@"title": @"Another Bar Chart",
@"subtitle": @"Implementation of a BarChart that only shows values at the bottom.",
@"class": AnotherBarChartViewController.class
},
@{
@"title": @"Multiple Lines Chart",
@"subtitle": @"A line chart with multiple DataSet objects. One color per DataSet.",
@"class": MultipleLinesChartViewController.class
},
@{
@"title": @"Multiple Bars Chart",
@"subtitle": @"A bar chart with multiple DataSet objects. One multiple colors per DataSet.",
@"class": MultipleBarChartViewController.class
},
@{
@"title": @"Candle Stick Chart",
@"subtitle": @"Demonstrates usage of the CandleStickChart.",
@"class": CandleStickChartViewController.class
},
@{
@"title": @"Cubic Line Chart",
@"subtitle": @"Demonstrates cubic lines in a LineChart.",
@"class": CubicLineChartViewController.class
},
@{
@"title": @"Radar Chart",
@"subtitle": @"Demonstrates the use of a spider-web like (net) chart.",
@"class": RadarChartViewController.class
},
@{
@"title": @"Colored Line Chart",
@"subtitle": @"Shows a LineChart with different background and line color.",
@"class": ColoredLineChartViewController.class
},
@{
@"title": @"Sinus Bar Chart",
@"subtitle": @"A Bar Chart plotting the sinus function with 8.000 values.",
@"class": SinusBarChartViewController.class
},
@{
@"title": @"BarChart positive / negative",
@"subtitle": @"This demonstrates how to create a BarChart with positive and negative values in different colors.",
@"class": PositiveNegativeBarChartViewController.class
},
@{
@"title": @"Time Line Chart",
@"subtitle": @"Simple demonstration of a time-chart. This chart draws one line entry per hour originating from the current time in milliseconds.",
@"class": LineChartTimeViewController.class
},
@{
@"title": @"Filled Line Chart",
@"subtitle": @"This demonstrates how to fill an area between two LineDataSets.",
@"class": LineChartFilledViewController.class
},
@{
@"title": @"Half Pie Chart",
@"subtitle": @"This demonstrates how to create a 180 degree PieChart.",
@"class": HalfPieChartViewController.class
}
];
//FIXME: Add TimeLineChart
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableViewDataSource, UITableViewDelegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.itemDefs.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70.f;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *def = self.itemDefs[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
}
cell.textLabel.text = def[@"title"];
cell.detailTextLabel.text = def[@"subtitle"];
cell.detailTextLabel.numberOfLines = 0;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *def = self.itemDefs[indexPath.row];
Class vcClass = def[@"class"];
UIViewController *vc = [[vcClass alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
@end
//
// AnotherBarChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface AnotherBarChartViewController : DemoBaseViewController
@end
//
// AnotherBarChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "AnotherBarChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface AnotherBarChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet BarChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation AnotherBarChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Another Bar Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
@{@"key": @"toggleBarBorders", @"label": @"Show Bar Borders"},
];
_chartView.delegate = self;
_chartView.chartDescription.enabled = NO;
_chartView.maxVisibleCount = 60;
_chartView.pinchZoomEnabled = NO;
_chartView.drawBarShadowEnabled = NO;
_chartView.drawGridBackgroundEnabled = NO;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.drawGridLinesEnabled = NO;
_chartView.leftAxis.drawGridLinesEnabled = NO;
_chartView.rightAxis.drawGridLinesEnabled = NO;
_chartView.legend.enabled = NO;
_sliderX.value = 10.0;
_sliderY.value = 100.0;
[self slidersValueChanged:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value + 1 range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double mult = (range + 1);
double val = (double) (arc4random_uniform(mult)) + mult / 3.0;
[yVals addObject:[[BarChartDataEntry alloc] initWithX:i y:val]];
}
BarChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (BarChartDataSet *)_chartView.data.dataSets[0];
[set1 replaceEntries:yVals];
[_chartView.data notifyDataChanged];
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[BarChartDataSet alloc] initWithEntries:yVals label:@"DataSet"];
set1.colors = ChartColorTemplates.vordiplom;
set1.drawValuesEnabled = NO;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *data = [[BarChartData alloc] initWithDataSets:dataSets];
_chartView.data = data;
_chartView.fitBars = YES;
}
[_chartView setNeedsDisplay];
}
- (void)optionTapped:(NSString *)key
{
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// BarChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface BarChartViewController : DemoBaseViewController
@end
//
// BarChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "BarChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
#import "DayAxisValueFormatter.h"
@interface BarChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet BarChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation BarChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Bar Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleIcons", @"label": @"Toggle Icons"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
@{@"key": @"toggleBarBorders", @"label": @"Show Bar Borders"},
];
[self setupBarLineChartView:_chartView];
_chartView.delegate = self;
_chartView.drawBarShadowEnabled = NO;
_chartView.drawValueAboveBarEnabled = YES;
_chartView.maxVisibleCount = 60;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawGridLinesEnabled = NO;
xAxis.granularity = 1.0; // only intervals of 1 day
xAxis.labelCount = 7;
xAxis.valueFormatter = [[DayAxisValueFormatter alloc] initForChart:_chartView];
NSNumberFormatter *leftAxisFormatter = [[NSNumberFormatter alloc] init];
leftAxisFormatter.minimumFractionDigits = 0;
leftAxisFormatter.maximumFractionDigits = 1;
leftAxisFormatter.negativeSuffix = @" $";
leftAxisFormatter.positiveSuffix = @" $";
ChartYAxis *leftAxis = _chartView.leftAxis;
leftAxis.labelFont = [UIFont systemFontOfSize:10.f];
leftAxis.labelCount = 8;
leftAxis.valueFormatter = [[ChartDefaultAxisValueFormatter alloc] initWithFormatter:leftAxisFormatter];
leftAxis.labelPosition = YAxisLabelPositionOutsideChart;
leftAxis.spaceTop = 0.15;
leftAxis.axisMinimum = 0.0; // this replaces startAtZero = YES
ChartYAxis *rightAxis = _chartView.rightAxis;
rightAxis.enabled = YES;
rightAxis.drawGridLinesEnabled = NO;
rightAxis.labelFont = [UIFont systemFontOfSize:10.f];
rightAxis.labelCount = 8;
rightAxis.valueFormatter = leftAxis.valueFormatter;
rightAxis.spaceTop = 0.15;
rightAxis.axisMinimum = 0.0; // this replaces startAtZero = YES
ChartLegend *l = _chartView.legend;
l.horizontalAlignment = ChartLegendHorizontalAlignmentLeft;
l.verticalAlignment = ChartLegendVerticalAlignmentBottom;
l.orientation = ChartLegendOrientationHorizontal;
l.drawInside = NO;
l.form = ChartLegendFormSquare;
l.formSize = 9.0;
l.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:11.f];
l.xEntrySpace = 4.0;
XYMarkerView *marker = [[XYMarkerView alloc]
initWithColor: [UIColor colorWithWhite:180/255. alpha:1.0]
font: [UIFont systemFontOfSize:12.0]
textColor: UIColor.whiteColor
insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0)
xAxisValueFormatter: _chartView.xAxis.valueFormatter];
marker.chartView = _chartView;
marker.minimumSize = CGSizeMake(80.f, 40.f);
_chartView.marker = marker;
_sliderX.value = 12.0;
_sliderY.value = 50.0;
[self slidersValueChanged:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value + 1 range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
double start = 1.0;
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = start; i < start + count + 1; i++)
{
double mult = (range + 1);
double val = (double) (arc4random_uniform(mult));
if (arc4random_uniform(100) < 25) {
[yVals addObject:[[BarChartDataEntry alloc] initWithX:i y:val icon: [UIImage imageNamed:@"icon"]]];
} else {
[yVals addObject:[[BarChartDataEntry alloc] initWithX:i y:val]];
}
}
BarChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (BarChartDataSet *)_chartView.data.dataSets[0];
[set1 replaceEntries: yVals];
[_chartView.data notifyDataChanged];
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[BarChartDataSet alloc] initWithEntries:yVals label:@"The year 2017"];
[set1 setColors:ChartColorTemplates.material];
set1.drawIconsEnabled = NO;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *data = [[BarChartData alloc] initWithDataSets:dataSets];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
data.barWidth = 0.9f;
_chartView.data = data;
}
}
- (void)optionTapped:(NSString *)key
{
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value + 2) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// BubbleChartViewController.h
// ChartsDemo
//
// Bubble chart implementation:
// Copyright 2015 Pierre-Marc Airoldi
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface BubbleChartViewController : DemoBaseViewController
@end
//
// BubbleChartViewController.m
// ChartsDemo
//
// Bubble chart implementation:
// Copyright 2015 Pierre-Marc Airoldi
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "BubbleChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface BubbleChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet BubbleChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation BubbleChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Bubble Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleIcons", @"label": @"Toggle Icons"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
];
_chartView.delegate = self;
_chartView.chartDescription.enabled = NO;
_chartView.drawGridBackgroundEnabled = NO;
_chartView.dragEnabled = YES;
[_chartView setScaleEnabled:YES];
_chartView.maxVisibleCount = 200;
_chartView.pinchZoomEnabled = YES;
ChartLegend *l = _chartView.legend;
l.horizontalAlignment = ChartLegendHorizontalAlignmentRight;
l.verticalAlignment = ChartLegendVerticalAlignmentTop;
l.orientation = ChartLegendOrientationVertical;
l.drawInside = NO;
l.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.f];
ChartYAxis *yl = _chartView.leftAxis;
yl.labelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.f];
yl.spaceTop = 0.3;
yl.spaceBottom = 0.3;
yl.axisMinimum = 0.0; // this replaces startAtZero = YES
_chartView.rightAxis.enabled = NO;
ChartXAxis *xl = _chartView.xAxis;
xl.labelPosition = XAxisLabelPositionBottom;
xl.labelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.f];
_sliderX.value = 10.0;
_sliderY.value = 50.0;
[self slidersValueChanged:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
NSMutableArray *yVals1 = [[NSMutableArray alloc] init];
NSMutableArray *yVals2 = [[NSMutableArray alloc] init];
NSMutableArray *yVals3 = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double val = (double) (arc4random_uniform(range));
double size = (double) (arc4random_uniform(range));
[yVals1 addObject:[[BubbleChartDataEntry alloc] initWithX:i y:val size:size icon: [UIImage imageNamed:@"icon"]]];
val = (double) (arc4random_uniform(range));
size = (double) (arc4random_uniform(range));
[yVals2 addObject:[[BubbleChartDataEntry alloc] initWithX:i y:val size:size icon: [UIImage imageNamed:@"icon"]]];
val = (double) (arc4random_uniform(range));
size = (double) (arc4random_uniform(range));
[yVals3 addObject:[[BubbleChartDataEntry alloc] initWithX:i y:val size:size]];
}
BubbleChartDataSet *set1 = [[BubbleChartDataSet alloc] initWithEntries:yVals1 label:@"DS 1"];
set1.drawIconsEnabled = NO;
[set1 setColor:ChartColorTemplates.colorful[0] alpha:0.50f];
[set1 setDrawValuesEnabled:YES];
BubbleChartDataSet *set2 = [[BubbleChartDataSet alloc] initWithEntries:yVals2 label:@"DS 2"];
set2.iconsOffset = CGPointMake(0, 15);
[set2 setColor:ChartColorTemplates.colorful[1] alpha:0.50f];
[set2 setDrawValuesEnabled:YES];
BubbleChartDataSet *set3 = [[BubbleChartDataSet alloc] initWithEntries:yVals3 label:@"DS 3"];
[set3 setColor:ChartColorTemplates.colorful[2] alpha:0.50f];
[set3 setDrawValuesEnabled:YES];
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
[dataSets addObject:set2];
[dataSets addObject:set3];
BubbleChartData *data = [[BubbleChartData alloc] initWithDataSets:dataSets];
[data setDrawValues:NO];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:7.f]];
[data setHighlightCircleWidth: 1.5];
[data setValueTextColor:UIColor.whiteColor];
_chartView.data = data;
}
- (void)optionTapped:(NSString *)key
{
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull )entry dataSetIndex:(NSInteger)dataSetIndex highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// CandleStickChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface CandleStickChartViewController : DemoBaseViewController
@end
//
// CandleStickChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "CandleStickChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface CandleStickChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet CandleStickChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation CandleStickChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Candle Stick Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleIcons", @"label": @"Toggle Icons"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleShadowColorSameAsCandle", @"label": @"Toggle shadow same color"},
@{@"key": @"toggleShowCandleBar", @"label": @"Toggle show candle bar"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
];
_chartView.delegate = self;
_chartView.chartDescription.enabled = NO;
_chartView.maxVisibleCount = 60;
_chartView.pinchZoomEnabled = NO;
_chartView.drawGridBackgroundEnabled = NO;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.drawGridLinesEnabled = NO;
ChartYAxis *leftAxis = _chartView.leftAxis;
leftAxis.labelCount = 7;
leftAxis.drawGridLinesEnabled = NO;
leftAxis.drawAxisLineEnabled = NO;
ChartYAxis *rightAxis = _chartView.rightAxis;
rightAxis.enabled = NO;
_chartView.legend.enabled = NO;
_sliderX.value = 40.0;
_sliderY.value = 100.0;
[self slidersValueChanged:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value + 1 range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
NSMutableArray *yVals1 = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double mult = (range + 1);
double val = (double) (arc4random_uniform(40)) + mult;
double high = (double) (arc4random_uniform(9)) + 8.0;
double low = (double) (arc4random_uniform(9)) + 8.0;
double open = (double) (arc4random_uniform(6)) + 1.0;
double close = (double) (arc4random_uniform(6)) + 1.0;
BOOL even = i % 2 == 0;
[yVals1 addObject:[[CandleChartDataEntry alloc] initWithX:i shadowH:val + high shadowL:val - low open:even ? val + open : val - open close:even ? val - close : val + close icon: [UIImage imageNamed:@"icon"]]];
}
CandleChartDataSet *set1 = [[CandleChartDataSet alloc] initWithEntries:yVals1 label:@"Data Set"];
set1.axisDependency = AxisDependencyLeft;
[set1 setColor:[UIColor colorWithWhite:80/255.f alpha:1.f]];
set1.drawIconsEnabled = NO;
set1.shadowColor = UIColor.darkGrayColor;
set1.shadowWidth = 0.7;
set1.decreasingColor = UIColor.redColor;
set1.decreasingFilled = YES;
set1.increasingColor = [UIColor colorWithRed:122/255.f green:242/255.f blue:84/255.f alpha:1.f];
set1.increasingFilled = NO;
set1.neutralColor = UIColor.blueColor;
CandleChartData *data = [[CandleChartData alloc] initWithDataSet:set1];
_chartView.data = data;
}
- (void)optionTapped:(NSString *)key
{
if ([key isEqualToString:@"toggleShadowColorSameAsCandle"])
{
for (id<CandleChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.shadowColorSameAsCandle = !set.shadowColorSameAsCandle;
}
[_chartView notifyDataSetChanged];
return;
} else if ([key isEqualToString:@"toggleShowCandleBar"])
{
for (id<CandleChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.showCandleBar = !set.showCandleBar;
}
[_chartView notifyDataSetChanged];
return;
}
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// ColoredLineChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface ColoredLineChartViewController : DemoBaseViewController
@end
//
// ColoredLineChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "ColoredLineChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface ColoredLineChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutletCollection(LineChartView) NSArray *chartViews;
@end
@implementation ColoredLineChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Colored Line Chart";
for (int i = 0; i < _chartViews.count; i++)
{
LineChartData *data = [self dataWithCount:36 range:100];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:7.f]];
NSArray *colors = @[
[UIColor colorWithRed:137/255.f green:230/255.f blue:81/255.f alpha:1.f],
[UIColor colorWithRed:240/255.f green:240/255.f blue:30/255.f alpha:1.f],
[UIColor colorWithRed:89/255.f green:199/255.f blue:250/255.f alpha:1.f],
[UIColor colorWithRed:250/255.f green:104/255.f blue:104/255.f alpha:1.f],
];
[self setupChart:_chartViews[i] data:data color:colors[i % colors.count]];
}
}
- (void)setupChart:(LineChartView *)chart data:(LineChartData *)data color:(UIColor *)color
{
[(LineChartDataSet *)[data dataSetAtIndex:0] setCircleHoleColor:color];
chart.delegate = self;
chart.backgroundColor = color;
chart.chartDescription.enabled = NO;
chart.drawGridBackgroundEnabled = NO;
chart.dragEnabled = YES;
[chart setScaleEnabled:YES];
chart.pinchZoomEnabled = NO;
[chart setViewPortOffsetsWithLeft:10.0 top:0.0 right:10.0 bottom:0.0];
chart.legend.enabled = NO;
chart.leftAxis.enabled = NO;
chart.leftAxis.spaceTop = 0.4;
chart.leftAxis.spaceBottom = 0.4;
chart.rightAxis.enabled = NO;
chart.xAxis.enabled = NO;
chart.data = data;
[chart animateWithXAxisDuration:2.5];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (LineChartData *)dataWithCount:(int)count range:(double)range
{
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double val = (double) (arc4random_uniform(range)) + 3;
[yVals addObject:[[ChartDataEntry alloc] initWithX:i y:val]];
}
LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithEntries:yVals label:@"DataSet 1"];
set1.lineWidth = 1.75;
set1.circleRadius = 5.0;
set1.circleHoleRadius = 2.5f;
[set1 setColor:UIColor.whiteColor];
[set1 setCircleColor:UIColor.whiteColor];
set1.highlightColor = UIColor.whiteColor;
set1.drawValuesEnabled = NO;
return [[LineChartData alloc] initWithDataSet:set1];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// CombinedChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface CombinedChartViewController : DemoBaseViewController
@end
This diff is collapsed.
//
// CubicLineChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface CubicLineChartViewController : DemoBaseViewController
@end
//
// CubicLineChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "CubicLineChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface CubicLineSampleFillFormatter : NSObject <ChartFillFormatter>
{
}
@end
@implementation CubicLineSampleFillFormatter
- (CGFloat)getFillLinePositionWithDataSet:(LineChartDataSet *)dataSet dataProvider:(id<LineChartDataProvider>)dataProvider
{
return -10.f;
}
@end
@interface CubicLineChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet LineChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation CubicLineChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Cubic Line Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleFilled", @"label": @"Toggle Filled"},
@{@"key": @"toggleCircles", @"label": @"Toggle Circles"},
@{@"key": @"toggleCubic", @"label": @"Toggle Cubic"},
@{@"key": @"toggleHorizontalCubic", @"label": @"Toggle Horizontal Cubic"},
@{@"key": @"toggleStepped", @"label": @"Toggle Stepped"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
];
_chartView.delegate = self;
[_chartView setViewPortOffsetsWithLeft:0.f top:20.f right:0.f bottom:0.f];
_chartView.backgroundColor = [UIColor colorWithRed:104/255.f green:241/255.f blue:175/255.f alpha:1.f];
_chartView.chartDescription.enabled = NO;
_chartView.dragEnabled = YES;
[_chartView setScaleEnabled:YES];
_chartView.pinchZoomEnabled = NO;
_chartView.drawGridBackgroundEnabled = NO;
_chartView.maxHighlightDistance = 300.0;
_chartView.xAxis.enabled = NO;
ChartYAxis *yAxis = _chartView.leftAxis;
yAxis.labelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:12.f];
[yAxis setLabelCount:6 force:NO];
yAxis.labelTextColor = UIColor.whiteColor;
yAxis.labelPosition = YAxisLabelPositionInsideChart;
yAxis.drawGridLinesEnabled = NO;
yAxis.axisLineColor = UIColor.whiteColor;
_chartView.rightAxis.enabled = NO;
_chartView.legend.enabled = NO;
_sliderX.value = 45.0;
_sliderY.value = 100.0;
[self slidersValueChanged:nil];
[_chartView animateWithXAxisDuration:2.0 yAxisDuration:2.0];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value + 1 range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
NSMutableArray *yVals1 = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double mult = (range + 1);
double val = (double) (arc4random_uniform(mult)) + 20;
[yVals1 addObject:[[ChartDataEntry alloc] initWithX:i y:val]];
}
LineChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (LineChartDataSet *)_chartView.data.dataSets[0];
[set1 replaceEntries:yVals1];
[_chartView.data notifyDataChanged];
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[LineChartDataSet alloc] initWithEntries:yVals1 label:@"DataSet 1"];
set1.mode = LineChartModeCubicBezier;
set1.cubicIntensity = 0.2;
set1.drawCirclesEnabled = NO;
set1.lineWidth = 1.8;
set1.circleRadius = 4.0;
[set1 setCircleColor:UIColor.whiteColor];
set1.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f];
[set1 setColor:UIColor.whiteColor];
set1.fillColor = UIColor.whiteColor;
set1.fillAlpha = 1.f;
set1.drawHorizontalHighlightIndicatorEnabled = NO;
set1.fillFormatter = [[CubicLineSampleFillFormatter alloc] init];
LineChartData *data = [[LineChartData alloc] initWithDataSet:set1];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:9.f]];
[data setDrawValues:NO];
_chartView.data = data;
}
}
- (void)optionTapped:(NSString *)key
{
if ([key isEqualToString:@"toggleFilled"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.drawFilledEnabled = !set.isDrawFilledEnabled;
}
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleCircles"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.drawCirclesEnabled = !set.isDrawCirclesEnabled;
}
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleCubic"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.mode = set.mode == LineChartModeCubicBezier ? LineChartModeLinear : LineChartModeCubicBezier;
}
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleStepped"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.mode = set.mode == LineChartModeStepped ? LineChartModeLinear : LineChartModeStepped;
}
[_chartView setNeedsDisplay];
}
if ([key isEqualToString:@"toggleHorizontalCubic"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.mode = set.mode == LineChartModeCubicBezier ? LineChartModeHorizontalBezier : LineChartModeCubicBezier;
}
[_chartView setNeedsDisplay];
return;
}
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// HalfPieChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface HalfPieChartViewController : DemoBaseViewController
@end
//
// HalfPieChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "HalfPieChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface HalfPieChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet PieChartView *chartView;
@end
@implementation HalfPieChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Half Pie Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Y-Values"},
@{@"key": @"toggleXValues", @"label": @"Toggle X-Values"},
@{@"key": @"togglePercent", @"label": @"Toggle Percent"},
@{@"key": @"toggleHole", @"label": @"Toggle Hole"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"spin", @"label": @"Spin"},
@{@"key": @"drawCenter", @"label": @"Draw CenterText"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
];
[self setupPieChartView:_chartView];
_chartView.delegate = self;
_chartView.holeColor = UIColor.whiteColor;
_chartView.transparentCircleColor = [UIColor.whiteColor colorWithAlphaComponent:0.43];
_chartView.holeRadiusPercent = 0.58;
_chartView.rotationEnabled = NO;
_chartView.highlightPerTapEnabled = YES;
_chartView.maxAngle = 180.0; // Half chart
_chartView.rotationAngle = 180.0; // Rotate to make the half on the upper side
_chartView.centerTextOffset = CGPointMake(0.0, -20.0);
ChartLegend *l = _chartView.legend;
l.horizontalAlignment = ChartLegendHorizontalAlignmentCenter;
l.verticalAlignment = ChartLegendVerticalAlignmentTop;
l.orientation = ChartLegendOrientationHorizontal;
l.drawInside = NO;
l.xEntrySpace = 7.0;
l.yEntrySpace = 0.0;
l.yOffset = 0.0;
// entry label styling
_chartView.entryLabelColor = UIColor.whiteColor;
_chartView.entryLabelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:12.f];
[self updateChartData];
[_chartView animateWithXAxisDuration:1.4 easingOption:ChartEasingOptionEaseOutBack];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:4 range:100];
}
- (void)setDataCount:(int)count range:(double)range
{
double mult = range;
NSMutableArray *values = [[NSMutableArray alloc] init];
// IMPORTANT: In a PieChart, no values (Entry) should have the same xIndex (even if from different DataSets), since no values can be drawn above each other.
for (int i = 0; i < count; i++)
{
[values addObject:[[PieChartDataEntry alloc] initWithValue:(arc4random_uniform(mult) + mult / 5) label:parties[i % parties.count]]];
}
PieChartDataSet *dataSet = [[PieChartDataSet alloc] initWithEntries:values label:@"Election Results"];
dataSet.sliceSpace = 3.0;
dataSet.selectionShift = 5.0;
dataSet.colors = ChartColorTemplates.material;
PieChartData *data = [[PieChartData alloc] initWithDataSet:dataSet];
NSNumberFormatter *pFormatter = [[NSNumberFormatter alloc] init];
pFormatter.numberStyle = NSNumberFormatterPercentStyle;
pFormatter.maximumFractionDigits = 1;
pFormatter.multiplier = @1.f;
pFormatter.percentSymbol = @" %";
[data setValueFormatter:[[ChartDefaultValueFormatter alloc] initWithFormatter:pFormatter]];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:11.f]];
[data setValueTextColor:UIColor.whiteColor];
_chartView.data = data;
[_chartView setNeedsDisplay];
}
- (void)optionTapped:(NSString *)key
{
if ([key isEqualToString:@"toggleXValues"])
{
_chartView.drawEntryLabelsEnabled = !_chartView.drawEntryLabelsEnabled;
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"togglePercent"])
{
_chartView.usePercentValuesEnabled = !_chartView.isUsePercentValuesEnabled;
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleHole"])
{
_chartView.drawHoleEnabled = !_chartView.isDrawHoleEnabled;
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"drawCenter"])
{
_chartView.drawCenterTextEnabled = !_chartView.isDrawCenterTextEnabled;
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"animateX"])
{
[_chartView animateWithXAxisDuration:1.4];
return;
}
if ([key isEqualToString:@"animateY"])
{
[_chartView animateWithYAxisDuration:1.4];
return;
}
if ([key isEqualToString:@"animateXY"])
{
[_chartView animateWithXAxisDuration:1.4 yAxisDuration:1.4];
return;
}
if ([key isEqualToString:@"spin"])
{
[_chartView spinWithDuration:2.0 fromAngle:_chartView.rotationAngle toAngle:_chartView.rotationAngle + 360.f easingOption:ChartEasingOptionEaseInCubic];
return;
}
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Action
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// HorizontalBarChartViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface HorizontalBarChartViewController : DemoBaseViewController
@end
//
// HorizontalBarChartViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "HorizontalBarChartViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface HorizontalBarChartViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet HorizontalBarChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation HorizontalBarChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Horizontal Bar Chart";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleIcons", @"label": @"Toggle Icons"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
@{@"key": @"toggleBarBorders", @"label": @"Show Bar Borders"},
];
[self setupBarLineChartView:_chartView];
_chartView.delegate = self;
_chartView.drawBarShadowEnabled = NO;
_chartView.drawValueAboveBarEnabled = YES;
_chartView.maxVisibleCount = 60;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawAxisLineEnabled = YES;
xAxis.drawGridLinesEnabled = NO;
xAxis.granularity = 10.0;
ChartYAxis *leftAxis = _chartView.leftAxis;
leftAxis.labelFont = [UIFont systemFontOfSize:10.f];
leftAxis.drawAxisLineEnabled = YES;
leftAxis.drawGridLinesEnabled = YES;
leftAxis.axisMinimum = 0.0; // this replaces startAtZero = YES
ChartYAxis *rightAxis = _chartView.rightAxis;
rightAxis.enabled = YES;
rightAxis.labelFont = [UIFont systemFontOfSize:10.f];
rightAxis.drawAxisLineEnabled = YES;
rightAxis.drawGridLinesEnabled = NO;
rightAxis.axisMinimum = 0.0; // this replaces startAtZero = YES
ChartLegend *l = _chartView.legend;
l.horizontalAlignment = ChartLegendHorizontalAlignmentLeft;
l.verticalAlignment = ChartLegendVerticalAlignmentBottom;
l.orientation = ChartLegendOrientationHorizontal;
l.drawInside = NO;
l.form = ChartLegendFormSquare;
l.formSize = 8.0;
l.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:11.f];
l.xEntrySpace = 4.0;
_chartView.fitBars = YES;
_sliderX.value = 12.0;
_sliderY.value = 50.0;
[self slidersValueChanged:nil];
[_chartView animateWithYAxisDuration:2.5];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value + 1 range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
double barWidth = 9.0;
double spaceForBar = 10.0;
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double mult = (range + 1);
double val = (double) (arc4random_uniform(mult));
[yVals addObject:[[BarChartDataEntry alloc] initWithX:i * spaceForBar y:val icon: [UIImage imageNamed:@"icon"]]];
}
BarChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (BarChartDataSet *)_chartView.data.dataSets[0];
[set1 replaceEntries:yVals];
[_chartView.data notifyDataChanged];
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[BarChartDataSet alloc] initWithEntries:yVals label:@"DataSet"];
set1.drawIconsEnabled = NO;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *data = [[BarChartData alloc] initWithDataSets:dataSets];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
data.barWidth = barWidth;
_chartView.data = data;
}
}
- (void)optionTapped:(NSString *)key
{
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// LineChart1ViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface LineChart1ViewController : DemoBaseViewController
@end
//
// LineChart1ViewController.m
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import "LineChart1ViewController.h"
#import "ChartsDemo_iOS-Swift.h"
@interface LineChart1ViewController () <ChartViewDelegate>
@property (nonatomic, strong) IBOutlet LineChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;
@end
@implementation LineChart1ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Line Chart 1";
self.options = @[
@{@"key": @"toggleValues", @"label": @"Toggle Values"},
@{@"key": @"toggleFilled", @"label": @"Toggle Filled"},
@{@"key": @"toggleCircles", @"label": @"Toggle Circles"},
@{@"key": @"toggleCubic", @"label": @"Toggle Cubic"},
@{@"key": @"toggleHorizontalCubic", @"label": @"Toggle Horizontal Cubic"},
@{@"key": @"toggleIcons", @"label": @"Toggle Icons"},
@{@"key": @"toggleStepped", @"label": @"Toggle Stepped"},
@{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"},
@{@"key": @"animateX", @"label": @"Animate X"},
@{@"key": @"animateY", @"label": @"Animate Y"},
@{@"key": @"animateXY", @"label": @"Animate XY"},
@{@"key": @"saveToGallery", @"label": @"Save to Camera Roll"},
@{@"key": @"togglePinchZoom", @"label": @"Toggle PinchZoom"},
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
];
_chartView.delegate = self;
_chartView.chartDescription.enabled = NO;
_chartView.dragEnabled = YES;
[_chartView setScaleEnabled:YES];
_chartView.pinchZoomEnabled = YES;
_chartView.drawGridBackgroundEnabled = NO;
// x-axis limit line
ChartLimitLine *llXAxis = [[ChartLimitLine alloc] initWithLimit:10.0 label:@"Index 10"];
llXAxis.lineWidth = 4.0;
llXAxis.lineDashLengths = @[@(10.f), @(10.f), @(0.f)];
llXAxis.labelPosition = ChartLimitLabelPositionRightBottom;
llXAxis.valueFont = [UIFont systemFontOfSize:10.f];
//[_chartView.xAxis addLimitLine:llXAxis];
_chartView.xAxis.gridLineDashLengths = @[@10.0, @10.0];
_chartView.xAxis.gridLineDashPhase = 0.f;
ChartLimitLine *ll1 = [[ChartLimitLine alloc] initWithLimit:150.0 label:@"Upper Limit"];
ll1.lineWidth = 4.0;
ll1.lineDashLengths = @[@5.f, @5.f];
ll1.labelPosition = ChartLimitLabelPositionRightTop;
ll1.valueFont = [UIFont systemFontOfSize:10.0];
ChartLimitLine *ll2 = [[ChartLimitLine alloc] initWithLimit:-30.0 label:@"Lower Limit"];
ll2.lineWidth = 4.0;
ll2.lineDashLengths = @[@5.f, @5.f];
ll2.labelPosition = ChartLimitLabelPositionRightBottom;
ll2.valueFont = [UIFont systemFontOfSize:10.0];
ChartYAxis *leftAxis = _chartView.leftAxis;
[leftAxis removeAllLimitLines];
[leftAxis addLimitLine:ll1];
[leftAxis addLimitLine:ll2];
leftAxis.axisMaximum = 200.0;
leftAxis.axisMinimum = -50.0;
leftAxis.gridLineDashLengths = @[@5.f, @5.f];
leftAxis.drawZeroLineEnabled = NO;
leftAxis.drawLimitLinesBehindDataEnabled = YES;
_chartView.rightAxis.enabled = NO;
//[_chartView.viewPortHandler setMaximumScaleY: 2.f];
//[_chartView.viewPortHandler setMaximumScaleX: 2.f];
BalloonMarker *marker = [[BalloonMarker alloc]
initWithColor: [UIColor colorWithWhite:180/255. alpha:1.0]
font: [UIFont systemFontOfSize:12.0]
textColor: UIColor.whiteColor
insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0)];
marker.chartView = _chartView;
marker.minimumSize = CGSizeMake(80.f, 40.f);
_chartView.marker = marker;
_chartView.legend.form = ChartLegendFormLine;
_sliderX.value = 45.0;
_sliderY.value = 100.0;
[self slidersValueChanged:nil];
[_chartView animateWithXAxisDuration:2.5];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)updateChartData
{
if (self.shouldHideData)
{
_chartView.data = nil;
return;
}
[self setDataCount:_sliderX.value range:_sliderY.value];
}
- (void)setDataCount:(int)count range:(double)range
{
NSMutableArray *values = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++)
{
double val = arc4random_uniform(range) + 3;
[values addObject:[[ChartDataEntry alloc] initWithX:i y:val icon: [UIImage imageNamed:@"icon"]]];
}
LineChartDataSet *set1 = nil;
if (_chartView.data.dataSetCount > 0)
{
set1 = (LineChartDataSet *)_chartView.data.dataSets[0];
[set1 replaceEntries: values];
[_chartView.data notifyDataChanged];
[_chartView notifyDataSetChanged];
}
else
{
set1 = [[LineChartDataSet alloc] initWithEntries:values label:@"DataSet 1"];
set1.drawIconsEnabled = NO;
set1.lineDashLengths = @[@5.f, @2.5f];
set1.highlightLineDashLengths = @[@5.f, @2.5f];
[set1 setColor:UIColor.blackColor];
[set1 setCircleColor:UIColor.blackColor];
set1.lineWidth = 1.0;
set1.circleRadius = 3.0;
set1.drawCircleHoleEnabled = NO;
set1.valueFont = [UIFont systemFontOfSize:9.f];
set1.formLineDashLengths = @[@5.f, @2.5f];
set1.formLineWidth = 1.0;
set1.formSize = 15.0;
NSArray *gradientColors = @[
(id)[ChartColorTemplates colorFromString:@"#00ff0000"].CGColor,
(id)[ChartColorTemplates colorFromString:@"#ffff0000"].CGColor
];
CGGradientRef gradient = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil);
set1.fillAlpha = 1.f;
set1.fill = [[ChartLinearGradientFill alloc] initWithGradient:gradient angle:90.0f];
set1.drawFilledEnabled = YES;
CGGradientRelease(gradient);
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
LineChartData *data = [[LineChartData alloc] initWithDataSets:dataSets];
_chartView.data = data;
}
}
- (void)optionTapped:(NSString *)key
{
if ([key isEqualToString:@"toggleFilled"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.drawFilledEnabled = !set.isDrawFilledEnabled;
}
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleCircles"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.drawCirclesEnabled = !set.isDrawCirclesEnabled;
}
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleCubic"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.mode = set.mode == LineChartModeCubicBezier ? LineChartModeLinear : LineChartModeCubicBezier;
}
[_chartView setNeedsDisplay];
return;
}
if ([key isEqualToString:@"toggleStepped"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
switch (set.mode) {
case LineChartModeLinear:
case LineChartModeCubicBezier:
case LineChartModeHorizontalBezier:
set.mode = LineChartModeStepped;
break;
case LineChartModeStepped: set.mode = LineChartModeLinear;
}
}
[_chartView setNeedsDisplay];
}
if ([key isEqualToString:@"toggleHorizontalCubic"])
{
for (id<LineChartDataSetProtocol> set in _chartView.data.dataSets)
{
set.mode = set.mode == LineChartModeHorizontalBezier ? LineChartModeCubicBezier : LineChartModeHorizontalBezier;
}
[_chartView setNeedsDisplay];
return;
}
[super handleOption:key forChartView:_chartView];
}
#pragma mark - Actions
- (IBAction)slidersValueChanged:(id)sender
{
_sliderTextX.text = [@((int)_sliderX.value) stringValue];
_sliderTextY.text = [@((int)_sliderY.value) stringValue];
[self updateChartData];
}
#pragma mark - ChartViewDelegate
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight
{
NSLog(@"chartValueSelected");
}
- (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
{
NSLog(@"chartValueNothingSelected");
}
@end
//
// LineChart2ViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface LineChart2ViewController : DemoBaseViewController
@end
This diff is collapsed.
//
// LineChartFilledViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface LineChartFilledViewController : DemoBaseViewController
@end
//
// LineChartTimeViewController.h
// ChartsDemo
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
#import <UIKit/UIKit.h>
#import "DemoBaseViewController.h"
#import <Charts/Charts.h>
@interface LineChartTimeViewController : DemoBaseViewController
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment