From 0ce7d25fe8ecbc2e636dd316827ceafb9eb1837d Mon Sep 17 00:00:00 2001 From: Anatoly Rosencrantz Date: Mon, 28 Dec 2015 10:02:21 +0200 Subject: [PATCH 1/2] LineChartDataSet: for every data set image can be set for nodal points. LineChardRenderer: those images are drawn same way as circles --- Charts/Classes/Data/LineChartDataSet.swift | 8 +++ .../Classes/Renderers/LineChartRenderer.swift | 70 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/Charts/Classes/Data/LineChartDataSet.swift b/Charts/Classes/Data/LineChartDataSet.swift index eb308c4406..416e009953 100644 --- a/Charts/Classes/Data/LineChartDataSet.swift +++ b/Charts/Classes/Data/LineChartDataSet.swift @@ -23,6 +23,8 @@ public class LineChartDataSet: LineRadarChartDataSet private var _cubicIntensity = CGFloat(0.2) + public var nodalImage: UIImage? = nil + public var lineDashPhase = CGFloat(0.0) public var lineDashLengths: [CGFloat]! @@ -35,6 +37,9 @@ public class LineChartDataSet: LineRadarChartDataSet /// if true, cubic lines are drawn instead of linear public var drawCubicEnabled = false + /// if true, image is drawn on the nodal points + public var drawNodalImageEnabled = false + public var drawCircleHoleEnabled = true public required init() @@ -103,6 +108,8 @@ public class LineChartDataSet: LineRadarChartDataSet public var isDrawCubicEnabled: Bool { return drawCubicEnabled; } + public var isDrawNodalImageEnabled: Bool { return drawNodalImageEnabled; } + public var isDrawCircleHoleEnabled: Bool { return drawCircleHoleEnabled; } /// Sets a custom FillFormatter to the chart that handles the position of the filled-line for each DataSet. Set this to null to use the default logic. @@ -137,6 +144,7 @@ public class LineChartDataSet: LineRadarChartDataSet copy.lineDashLengths = lineDashLengths copy.drawCirclesEnabled = drawCirclesEnabled copy.drawCubicEnabled = drawCubicEnabled + copy.drawNodalImageEnabled = drawNodalImageEnabled return copy } } diff --git a/Charts/Classes/Renderers/LineChartRenderer.swift b/Charts/Classes/Renderers/LineChartRenderer.swift index d3da538684..08463107ab 100644 --- a/Charts/Classes/Renderers/LineChartRenderer.swift +++ b/Charts/Classes/Renderers/LineChartRenderer.swift @@ -455,6 +455,76 @@ public class LineChartRenderer: LineScatterCandleRadarChartRenderer public override func drawExtras(context context: CGContext) { drawCircles(context: context) + drawNodalImages(context: context) + } + + private func drawNodalImages(context context: CGContext) + { + guard let dataProvider = dataProvider, lineData = dataProvider.lineData else { return } + + let phaseX = _animator.phaseX + let phaseY = _animator.phaseY + + let dataSets = lineData.dataSets + + var pt = CGPoint() + var rect = CGRect() + + CGContextSaveGState(context) + + for (var i = 0, count = dataSets.count; i < count; i++) + { + let dataSet = lineData.getDataSetByIndex(i) as! LineChartDataSet! + + if !dataSet.isVisible || !dataSet.isDrawNodalImageEnabled || dataSet.entryCount == 0 + { + continue + } + + guard let nodalImage = dataSet.nodalImage else { + continue + } + + let trans = dataProvider.getTransformer(dataSet.axisDependency) + let valueToPixelMatrix = trans.valueToPixelMatrix + + var entries = dataSet.yVals + + let entryFrom = dataSet.entryForXIndex(_minX)! + let entryTo = dataSet.entryForXIndex(_maxX)! + + let diff = (entryFrom == entryTo) ? 1 : 0 + let minx = max(dataSet.entryIndex(entry: entryFrom, isEqual: true) - diff, 0) + let maxx = min(max(minx + 2, dataSet.entryIndex(entry: entryTo, isEqual: true) + 1), entries.count) + + for (var j = minx, count = Int(ceil(CGFloat(maxx - minx) * phaseX + CGFloat(minx))); j < count; j++) + { + let e = entries[j] + pt.x = CGFloat(e.xIndex) + pt.y = CGFloat(e.value) * phaseY + pt = CGPointApplyAffineTransform(pt, valueToPixelMatrix) + + if (!viewPortHandler.isInBoundsRight(pt.x)) + { + break + } + + // make sure the images don't do shitty things outside bounds + if (!viewPortHandler.isInBoundsLeft(pt.x) || !viewPortHandler.isInBoundsY(pt.y)) + { + continue + } + + rect.origin.x = pt.x - nodalImage.size.width/2 + rect.origin.y = pt.y - nodalImage.size.height/2 + rect.size.width = nodalImage.size.height + rect.size.height = nodalImage.size.height + + CGContextDrawImage(context, rect, dataSet.nodalImage?.CGImage) + } + } + + CGContextRestoreGState(context) } private func drawCircles(context context: CGContext) From 33de7d7b75897f65f9bf45f143b3bf22c09b7ec1 Mon Sep 17 00:00:00 2001 From: Anatoly Rosencrantz Date: Mon, 28 Dec 2015 11:26:13 +0200 Subject: [PATCH 2/2] Added: Demo view of nodal images on LineChart. Fixed: image now is not drawn upside down. --- .../Classes/Renderers/LineChartRenderer.swift | 2 +- .../ChartsDemo.xcodeproj/project.pbxproj | 50 +++- ChartsDemo/Classes/DemoListViewController.m | 6 + .../Classes/Demos/LineChart2ViewController.m | 2 + .../Demos/LineChart2ViewController.xib | 5 +- .../Classes/Demos/LineChart3ViewController.h | 20 ++ .../Classes/Demos/LineChart3ViewController.m | 271 ++++++++++++++++++ .../Demos/LineChart3ViewController.xib | 92 ++++++ .../Demos/MultipleBarChartViewController.xib | 5 +- .../Resources/Images.xcassets/Contents.json | 6 + .../node.imageset/Contents.json | 23 ++ .../node.imageset/favourites7 (1)-1.png | Bin 0 -> 479 bytes .../node.imageset/favourites7 (1)-2.png | Bin 0 -> 479 bytes .../node.imageset/favourites7 (1).png | Bin 0 -> 479 bytes 14 files changed, 472 insertions(+), 10 deletions(-) create mode 100644 ChartsDemo/Classes/Demos/LineChart3ViewController.h create mode 100644 ChartsDemo/Classes/Demos/LineChart3ViewController.m create mode 100644 ChartsDemo/Classes/Demos/LineChart3ViewController.xib create mode 100644 ChartsDemo/Resources/Images.xcassets/Contents.json create mode 100644 ChartsDemo/Resources/Images.xcassets/node.imageset/Contents.json create mode 100644 ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1)-1.png create mode 100644 ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1)-2.png create mode 100644 ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1).png diff --git a/Charts/Classes/Renderers/LineChartRenderer.swift b/Charts/Classes/Renderers/LineChartRenderer.swift index 08463107ab..63d92d6e69 100644 --- a/Charts/Classes/Renderers/LineChartRenderer.swift +++ b/Charts/Classes/Renderers/LineChartRenderer.swift @@ -520,7 +520,7 @@ public class LineChartRenderer: LineScatterCandleRadarChartRenderer rect.size.width = nodalImage.size.height rect.size.height = nodalImage.size.height - CGContextDrawImage(context, rect, dataSet.nodalImage?.CGImage) + nodalImage.drawInRect(rect) } } diff --git a/ChartsDemo/ChartsDemo.xcodeproj/project.pbxproj b/ChartsDemo/ChartsDemo.xcodeproj/project.pbxproj index 5dee983ce8..e6771fb0f5 100644 --- a/ChartsDemo/ChartsDemo.xcodeproj/project.pbxproj +++ b/ChartsDemo/ChartsDemo.xcodeproj/project.pbxproj @@ -26,10 +26,9 @@ 5B57BBB51A9B26AA0036A6CC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B57BBB41A9B26AA0036A6CC /* main.m */; }; 5B57BBB81A9B26AA0036A6CC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B57BBB71A9B26AA0036A6CC /* AppDelegate.m */; }; 5B57BBBB1A9B26AA0036A6CC /* DemoListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B57BBBA1A9B26AA0036A6CC /* DemoListViewController.m */; }; - 5B6654D11BB0A36F00890030 /* MyCustomXValueFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B6654D01BB0A36F00890030 /* MyCustomXValueFormatter.m */; settings = {ASSET_TAGS = (); }; }; + 5B6654D11BB0A36F00890030 /* MyCustomXValueFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B6654D01BB0A36F00890030 /* MyCustomXValueFormatter.m */; }; 5B8EAF241AB3271B009697AA /* DemoListViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B8EAF231AB3271B009697AA /* DemoListViewController.xib */; }; 5B8EAF281AB32CF5009697AA /* DemoBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B8EAF261AB32CF5009697AA /* DemoBaseViewController.m */; }; - 5B8EAF301AB32E15009697AA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5B8EAF2F1AB32E15009697AA /* Images.xcassets */; }; 5B8EAF3D1AB32F27009697AA /* Charts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B8EAF371AB32EA1009697AA /* Charts.framework */; }; 5B9624411B38608C007763E2 /* NegativeStackedBarChartViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B96243F1B38608C007763E2 /* NegativeStackedBarChartViewController.m */; }; 5B9624421B38608C007763E2 /* NegativeStackedBarChartViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B9624401B38608C007763E2 /* NegativeStackedBarChartViewController.xib */; }; @@ -65,6 +64,9 @@ 5BEAED3C1ABC199F0013F194 /* ColoredLineChartViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BEAED3A1ABC199F0013F194 /* ColoredLineChartViewController.xib */; }; 5BEAED401ABC1AC60013F194 /* SinusBarChartViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BEAED3E1ABC1AC60013F194 /* SinusBarChartViewController.m */; }; 5BEAED411ABC1AC60013F194 /* SinusBarChartViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BEAED3F1ABC1AC60013F194 /* SinusBarChartViewController.xib */; }; + D8DBF35D1C312FDF000E030E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D8DBF35C1C312FDF000E030E /* Images.xcassets */; }; + D8DBF3601C3131A5000E030E /* LineChart3ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D8DBF35F1C3131A5000E030E /* LineChart3ViewController.m */; }; + D8DBF3621C3132B9000E030E /* LineChart3ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D8DBF3611C3132B9000E030E /* LineChart3ViewController.xib */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -82,6 +84,20 @@ remoteGlobalIDString = 5BA8EC3F1A9D14DC00CE82E1; remoteInfo = Charts; }; + D8DBF3581C312FBC000E030E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B8EAF321AB32EA0009697AA /* Charts.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A52C5C371BAC5CA400594CDD; + remoteInfo = "Charts-TV"; + }; + D8DBF35A1C312FBC000E030E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B8EAF321AB32EA0009697AA /* Charts.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 06AEE7A21BDC3F8B009875AE; + remoteInfo = ChartsTests; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -129,7 +145,6 @@ 5B8EAF231AB3271B009697AA /* DemoListViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DemoListViewController.xib; sourceTree = ""; }; 5B8EAF251AB32CF5009697AA /* DemoBaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoBaseViewController.h; sourceTree = ""; }; 5B8EAF261AB32CF5009697AA /* DemoBaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoBaseViewController.m; sourceTree = ""; }; - 5B8EAF2F1AB32E15009697AA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 5B8EAF321AB32EA0009697AA /* Charts.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Charts.xcodeproj; path = ../Charts/Charts.xcodeproj; sourceTree = ""; }; 5B96243E1B38608C007763E2 /* NegativeStackedBarChartViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NegativeStackedBarChartViewController.h; sourceTree = ""; }; 5B96243F1B38608C007763E2 /* NegativeStackedBarChartViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NegativeStackedBarChartViewController.m; sourceTree = ""; }; @@ -181,6 +196,10 @@ 5BEAED3D1ABC1AC60013F194 /* SinusBarChartViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinusBarChartViewController.h; sourceTree = ""; }; 5BEAED3E1ABC1AC60013F194 /* SinusBarChartViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SinusBarChartViewController.m; sourceTree = ""; }; 5BEAED3F1ABC1AC60013F194 /* SinusBarChartViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SinusBarChartViewController.xib; sourceTree = ""; }; + D8DBF35C1C312FDF000E030E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + D8DBF35E1C3131A5000E030E /* LineChart3ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineChart3ViewController.h; sourceTree = ""; }; + D8DBF35F1C3131A5000E030E /* LineChart3ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LineChart3ViewController.m; sourceTree = ""; }; + D8DBF3611C3132B9000E030E /* LineChart3ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LineChart3ViewController.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -269,7 +288,7 @@ 5B8EAF2E1AB32E15009697AA /* Resources */ = { isa = PBXGroup; children = ( - 5B8EAF2F1AB32E15009697AA /* Images.xcassets */, + D8DBF35C1C312FDF000E030E /* Images.xcassets */, 5B43161E1AB8D8AE0009FCAA /* app-icon */, 5B4316301AB8D8B70009FCAA /* launch-image */, ); @@ -280,6 +299,8 @@ isa = PBXGroup; children = ( 5B8EAF371AB32EA1009697AA /* Charts.framework */, + D8DBF3591C312FBC000E030E /* Charts.framework */, + D8DBF35B1C312FBC000E030E /* ChartsTests.xctest */, ); name = Products; sourceTree = ""; @@ -327,6 +348,9 @@ 5BD47E5D1ABB3C91008FCEC6 /* LineChart2ViewController.h */, 5BD47E5E1ABB3C91008FCEC6 /* LineChart2ViewController.m */, 5BD47E5F1ABB3C91008FCEC6 /* LineChart2ViewController.xib */, + D8DBF35E1C3131A5000E030E /* LineChart3ViewController.h */, + D8DBF35F1C3131A5000E030E /* LineChart3ViewController.m */, + D8DBF3611C3132B9000E030E /* LineChart3ViewController.xib */, 5BEAED1F1ABC0BE20013F194 /* MultipleBarChartViewController.h */, 5BEAED201ABC0BE20013F194 /* MultipleBarChartViewController.m */, 5BEAED211ABC0BE20013F194 /* MultipleBarChartViewController.xib */, @@ -425,6 +449,20 @@ remoteRef = 5B8EAF361AB32EA1009697AA /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + D8DBF3591C312FBC000E030E /* Charts.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Charts.framework; + remoteRef = D8DBF3581C312FBC000E030E /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + D8DBF35B1C312FBC000E030E /* ChartsTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = ChartsTests.xctest; + remoteRef = D8DBF35A1C312FBC000E030E /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -432,8 +470,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5B8EAF301AB32E15009697AA /* Images.xcassets in Resources */, 5B43162B1AB8D8AE0009FCAA /* Icon-60@2x.png in Resources */, + D8DBF35D1C312FDF000E030E /* Images.xcassets in Resources */, 5B43162E1AB8D8AE0009FCAA /* iTunesArtwork@2x in Resources */, 5B4316281AB8D8AE0009FCAA /* Icon-29@3x.png in Resources */, 5B4316361AB8D8B70009FCAA /* Default-667h@2x.png in Resources */, @@ -461,6 +499,7 @@ 5B4316371AB8D8B70009FCAA /* Default-736h@3x.png in Resources */, 5B4316291AB8D8AE0009FCAA /* Icon-40@2x.png in Resources */, 5BEAED1E1ABBFB340013F194 /* StackedBarChartViewController.xib in Resources */, + D8DBF3621C3132B9000E030E /* LineChart3ViewController.xib in Resources */, 5B4316271AB8D8AE0009FCAA /* Icon-29@2x.png in Resources */, 55E356501ADC638F00A57971 /* BubbleChartViewController.xib in Resources */, 5B43162C1AB8D8AE0009FCAA /* Icon-60@3x.png in Resources */, @@ -478,6 +517,7 @@ 5B0CC7851ABB875400665592 /* PieChartViewController.m in Sources */, 5B57BBBB1A9B26AA0036A6CC /* DemoListViewController.m in Sources */, 5BD47E651ABB424E008FCEC6 /* BarChartViewController.m in Sources */, + D8DBF3601C3131A5000E030E /* LineChart3ViewController.m in Sources */, 5BDEDC471ABB871E007D3A60 /* CombinedChartViewController.m in Sources */, 5BD8F0741AB89CE500566E05 /* LineChart1ViewController.m in Sources */, 5BEAED401ABC1AC60013F194 /* SinusBarChartViewController.m in Sources */, diff --git a/ChartsDemo/Classes/DemoListViewController.m b/ChartsDemo/Classes/DemoListViewController.m index de3adaa572..422d174a9d 100644 --- a/ChartsDemo/Classes/DemoListViewController.m +++ b/ChartsDemo/Classes/DemoListViewController.m @@ -14,6 +14,7 @@ #import "DemoListViewController.h" #import "LineChart1ViewController.h" #import "LineChart2ViewController.h" +#import "LineChart3ViewController.h" #import "BarChartViewController.h" #import "HorizontalBarChartViewController.h" #import "CombinedChartViewController.h" @@ -56,6 +57,11 @@ - (void)viewDidLoad @"subtitle": @"Demonstration of the linechart with dual y-axis.", @"class": LineChart2ViewController.class }, + @{ + @"title": @"Line Chart (Image in nodes)", + @"subtitle": @"Demonstration of the linechart with dual y-axis and nodal images.", + @"class": LineChart3ViewController.class + }, @{ @"title": @"Bar Chart", @"subtitle": @"A simple demonstration of the bar chart.", diff --git a/ChartsDemo/Classes/Demos/LineChart2ViewController.m b/ChartsDemo/Classes/Demos/LineChart2ViewController.m index bffeb7bd4d..7237e6cbc8 100644 --- a/ChartsDemo/Classes/Demos/LineChart2ViewController.m +++ b/ChartsDemo/Classes/Demos/LineChart2ViewController.m @@ -124,6 +124,8 @@ - (void)setDataCount:(int)count range:(double)range set1.fillColor = [UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f]; set1.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f]; set1.drawCircleHoleEnabled = NO; + set1.drawNodalImageEnabled = NO; + set1.nodalImage = [UIImage imageNamed:@"node"]; NSMutableArray *yVals2 = [[NSMutableArray alloc] init]; diff --git a/ChartsDemo/Classes/Demos/LineChart2ViewController.xib b/ChartsDemo/Classes/Demos/LineChart2ViewController.xib index eb70c43187..895b559e64 100644 --- a/ChartsDemo/Classes/Demos/LineChart2ViewController.xib +++ b/ChartsDemo/Classes/Demos/LineChart2ViewController.xib @@ -1,7 +1,8 @@ - + - + + diff --git a/ChartsDemo/Classes/Demos/LineChart3ViewController.h b/ChartsDemo/Classes/Demos/LineChart3ViewController.h new file mode 100644 index 0000000000..88518da4a8 --- /dev/null +++ b/ChartsDemo/Classes/Demos/LineChart3ViewController.h @@ -0,0 +1,20 @@ +// +// LineChart3ViewController.h +// ChartsDemo +// +// Created by Anatoly Rosencrantz on 28/12/2015. +// +// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda +// A port of MPAndroidChart for iOS +// Licensed under Apache License 2.0 +// +// https://github.com/danielgindi/ios-charts +// + +#import +#import "DemoBaseViewController.h" +#import + +@interface LineChart3ViewController : DemoBaseViewController + +@end diff --git a/ChartsDemo/Classes/Demos/LineChart3ViewController.m b/ChartsDemo/Classes/Demos/LineChart3ViewController.m new file mode 100644 index 0000000000..09b90fdad6 --- /dev/null +++ b/ChartsDemo/Classes/Demos/LineChart3ViewController.m @@ -0,0 +1,271 @@ +// +// LineChart3ViewController.m +// ChartsDemo +// +// Created by Anatoly Rosencrantz on 28/12/2015. +// +// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda +// A port of MPAndroidChart for iOS +// Licensed under Apache License 2.0 +// +// https://github.com/danielgindi/ios-charts +// + +#import "LineChart3ViewController.h" +#import "ChartsDemo-Swift.h" + +@interface LineChart3ViewController () + +@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 LineChart3ViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.title = @"Line Chart 3 Chart"; + + self.options = @[ + @{@"key": @"toggleValues", @"label": @"Toggle Values"}, + @{@"key": @"toggleFilled", @"label": @"Toggle Filled"}, + @{@"key": @"toggleCircles", @"label": @"Toggle Circles"}, + @{@"key": @"toggleCubic", @"label": @"Toggle Cubic"}, + @{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"}, + @{@"key": @"toggleStartZero", @"label": @"Toggle StartZero"}, + @{@"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"}, + ]; + + _chartView.delegate = self; + + _chartView.descriptionText = @""; + _chartView.noDataTextDescription = @"You need to provide data for the chart."; + + _chartView.dragEnabled = YES; + [_chartView setScaleEnabled:YES]; + _chartView.drawGridBackgroundEnabled = NO; + _chartView.pinchZoomEnabled = YES; + + _chartView.backgroundColor = [UIColor colorWithWhite:204/255.f alpha:1.f]; + + _chartView.legend.form = ChartLegendFormLine; + _chartView.legend.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:11.f]; + _chartView.legend.textColor = UIColor.whiteColor; + _chartView.legend.position = ChartLegendPositionBelowChartLeft; + + ChartXAxis *xAxis = _chartView.xAxis; + xAxis.labelFont = [UIFont systemFontOfSize:12.f]; + xAxis.labelTextColor = UIColor.whiteColor; + xAxis.drawGridLinesEnabled = NO; + xAxis.drawAxisLineEnabled = NO; + xAxis.spaceBetweenLabels = 1.0; + + ChartYAxis *leftAxis = _chartView.leftAxis; + leftAxis.labelTextColor = [UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f]; + leftAxis.customAxisMax = 200.0; + leftAxis.drawGridLinesEnabled = YES; + + ChartYAxis *rightAxis = _chartView.rightAxis; + rightAxis.labelTextColor = UIColor.redColor; + rightAxis.customAxisMax = 900.0; + rightAxis.startAtZeroEnabled = NO; + rightAxis.customAxisMin = -200.0; + rightAxis.drawGridLinesEnabled = NO; + + _sliderX.value = 19.0; + _sliderY.value = 30.0; + [self slidersValueChanged:nil]; + + [_chartView animateWithXAxisDuration:2.5]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)setDataCount:(int)count range:(double)range +{ + NSMutableArray *xVals = [[NSMutableArray alloc] init]; + + for (int i = 0; i < count; i++) + { + [xVals addObject:[@(i) stringValue]]; + } + + NSMutableArray *yVals = [[NSMutableArray alloc] init]; + + for (int i = 0; i < count; i++) + { + double mult = range / 2.0; + double val = (double) (arc4random_uniform(mult)) + 50; + [yVals addObject:[[ChartDataEntry alloc] initWithValue:val xIndex:i]]; + } + + LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithYVals:yVals label:@"DataSet 1"]; + set1.axisDependency = AxisDependencyLeft; + [set1 setColor:[UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f]]; + set1.lineWidth = 2.0; + set1.fillAlpha = 65/255.0; + set1.fillColor = [UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f]; + set1.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f]; + set1.drawNodalImageEnabled = YES; + set1.drawCirclesEnabled = NO; + set1.nodalImage = [UIImage imageNamed:@"node"]; + + NSMutableArray *yVals2 = [[NSMutableArray alloc] init]; + + for (int i = 0; i < count; i++) + { + double mult = range; + double val = (double) (arc4random_uniform(mult)) + 450; + [yVals2 addObject:[[ChartDataEntry alloc] initWithValue:val xIndex:i]]; + } + + LineChartDataSet *set2 = [[LineChartDataSet alloc] initWithYVals:yVals2 label:@"DataSet 2"]; + set2.axisDependency = AxisDependencyRight; + [set2 setColor:UIColor.redColor]; + [set2 setCircleColor:UIColor.whiteColor]; + set2.lineWidth = 2.0; + set2.circleRadius = 3.0; + set2.fillAlpha = 65/255.0; + set2.fillColor = UIColor.redColor; + set2.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f]; + set2.drawCircleHoleEnabled = NO; + + NSMutableArray *dataSets = [[NSMutableArray alloc] init]; + [dataSets addObject:set2]; + [dataSets addObject:set1]; + + LineChartData *data = [[LineChartData alloc] initWithXVals:xVals dataSets:dataSets]; + [data setValueTextColor:UIColor.whiteColor]; + [data setValueFont:[UIFont systemFontOfSize:9.f]]; + + _chartView.data = data; +} + +- (void)optionTapped:(NSString *)key +{ + if ([key isEqualToString:@"toggleValues"]) + { + for (ChartDataSet *set in _chartView.data.dataSets) + { + set.drawValuesEnabled = !set.isDrawValuesEnabled; + } + + [_chartView setNeedsDisplay]; + } + + if ([key isEqualToString:@"toggleFilled"]) + { + for (LineChartDataSet *set in _chartView.data.dataSets) + { + set.drawFilledEnabled = !set.isDrawFilledEnabled; + } + + [_chartView setNeedsDisplay]; + } + + if ([key isEqualToString:@"toggleCircles"]) + { + for (LineChartDataSet *set in _chartView.data.dataSets) + { + set.drawCirclesEnabled = !set.isDrawCirclesEnabled; + } + + [_chartView setNeedsDisplay]; + } + + if ([key isEqualToString:@"toggleCubic"]) + { + for (LineChartDataSet *set in _chartView.data.dataSets) + { + set.drawCubicEnabled = !set.isDrawCubicEnabled; + } + + [_chartView setNeedsDisplay]; + } + + if ([key isEqualToString:@"toggleHighlight"]) + { + _chartView.data.highlightEnabled = !_chartView.data.isHighlightEnabled; + [_chartView setNeedsDisplay]; + } + + if ([key isEqualToString:@"toggleStartZero"]) + { + _chartView.leftAxis.startAtZeroEnabled = !_chartView.leftAxis.isStartAtZeroEnabled; + _chartView.rightAxis.startAtZeroEnabled = !_chartView.rightAxis.isStartAtZeroEnabled; + + [_chartView notifyDataSetChanged]; + } + + if ([key isEqualToString:@"animateX"]) + { + [_chartView animateWithXAxisDuration:3.0]; + } + + if ([key isEqualToString:@"animateY"]) + { + [_chartView animateWithYAxisDuration:3.0]; + } + + if ([key isEqualToString:@"animateXY"]) + { + [_chartView animateWithXAxisDuration:3.0 yAxisDuration:3.0]; + } + + if ([key isEqualToString:@"saveToGallery"]) + { + [_chartView saveToCameraRoll]; + } + + if ([key isEqualToString:@"togglePinchZoom"]) + { + _chartView.pinchZoomEnabled = !_chartView.isPinchZoomEnabled; + + [_chartView setNeedsDisplay]; + } + + if ([key isEqualToString:@"toggleAutoScaleMinMax"]) + { + _chartView.autoScaleMinMaxEnabled = !_chartView.isAutoScaleMinMaxEnabled; + [_chartView notifyDataSetChanged]; + } +} + +#pragma mark - Actions + +- (IBAction)slidersValueChanged:(id)sender +{ + _sliderTextX.text = [@((int)_sliderX.value + 1) stringValue]; + _sliderTextY.text = [@((int)_sliderY.value) stringValue]; + + [self setDataCount:(_sliderX.value + 1) range:_sliderY.value]; +} + +#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 diff --git a/ChartsDemo/Classes/Demos/LineChart3ViewController.xib b/ChartsDemo/Classes/Demos/LineChart3ViewController.xib new file mode 100644 index 0000000000..397ed577e9 --- /dev/null +++ b/ChartsDemo/Classes/Demos/LineChart3ViewController.xib @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ChartsDemo/Classes/Demos/MultipleBarChartViewController.xib b/ChartsDemo/Classes/Demos/MultipleBarChartViewController.xib index 6d27d969b4..8ce01951b0 100644 --- a/ChartsDemo/Classes/Demos/MultipleBarChartViewController.xib +++ b/ChartsDemo/Classes/Demos/MultipleBarChartViewController.xib @@ -1,7 +1,8 @@ - + - + + diff --git a/ChartsDemo/Resources/Images.xcassets/Contents.json b/ChartsDemo/Resources/Images.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/ChartsDemo/Resources/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ChartsDemo/Resources/Images.xcassets/node.imageset/Contents.json b/ChartsDemo/Resources/Images.xcassets/node.imageset/Contents.json new file mode 100644 index 0000000000..39187f138a --- /dev/null +++ b/ChartsDemo/Resources/Images.xcassets/node.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "favourites7 (1).png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "favourites7 (1)-1.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "favourites7 (1)-2.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1)-1.png b/ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1)-1.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd708463a178ae807cfd997def1d8ef750ee976 GIT binary patch literal 479 zcmV<50U-W~P)Ms2HsgP6OX z`24?!F-l@={3Eh+OSS^Ym5Zbh0>7Ne%RFV19~JV7o`Bgi5%Hb1^~L;0{f)^a3>v_VStn&!d6Lu zcZ3&3&c9qm!r1-f&x>dH`2fY)Z_~&*o9>R^NDxj7e9s%<0}K!jel{x)Kx_65wr@0; z+TV9VxsjMw9$W-W1U8|mkjRl0eD1Q-*o^dV%?d*MgZ4qRsBxZX!}&qPI@xT{z5uUV VjeXM)K_UPE002ovPDHLkV1f-Q(}e&4 literal 0 HcmV?d00001 diff --git a/ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1)-2.png b/ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1)-2.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd708463a178ae807cfd997def1d8ef750ee976 GIT binary patch literal 479 zcmV<50U-W~P)Ms2HsgP6OX z`24?!F-l@={3Eh+OSS^Ym5Zbh0>7Ne%RFV19~JV7o`Bgi5%Hb1^~L;0{f)^a3>v_VStn&!d6Lu zcZ3&3&c9qm!r1-f&x>dH`2fY)Z_~&*o9>R^NDxj7e9s%<0}K!jel{x)Kx_65wr@0; z+TV9VxsjMw9$W-W1U8|mkjRl0eD1Q-*o^dV%?d*MgZ4qRsBxZX!}&qPI@xT{z5uUV VjeXM)K_UPE002ovPDHLkV1f-Q(}e&4 literal 0 HcmV?d00001 diff --git a/ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1).png b/ChartsDemo/Resources/Images.xcassets/node.imageset/favourites7 (1).png new file mode 100644 index 0000000000000000000000000000000000000000..4dd708463a178ae807cfd997def1d8ef750ee976 GIT binary patch literal 479 zcmV<50U-W~P)Ms2HsgP6OX z`24?!F-l@={3Eh+OSS^Ym5Zbh0>7Ne%RFV19~JV7o`Bgi5%Hb1^~L;0{f)^a3>v_VStn&!d6Lu zcZ3&3&c9qm!r1-f&x>dH`2fY)Z_~&*o9>R^NDxj7e9s%<0}K!jel{x)Kx_65wr@0; z+TV9VxsjMw9$W-W1U8|mkjRl0eD1Q-*o^dV%?d*MgZ4qRsBxZX!}&qPI@xT{z5uUV VjeXM)K_UPE002ovPDHLkV1f-Q(}e&4 literal 0 HcmV?d00001