├── .gitignore ├── README.md ├── SCChart.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── MLS.xcuserdatad │ └── xcschemes │ ├── SCChart.xcscheme │ └── xcschememanagement.plist ├── SCChart ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── LaunchScreen.xib ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── SCBarCell.h ├── SCBarCell.m ├── SCChart │ ├── SCBar.h │ ├── SCBar.m │ ├── SCBarChart.h │ ├── SCBarChart.m │ ├── SCChart.h │ ├── SCChart.m │ ├── SCChartDelegate.h │ ├── SCChartLabel.h │ ├── SCChartLabel.m │ ├── SCCircleChart.h │ ├── SCCircleChart.m │ ├── SCColor.h │ ├── SCColor.m │ ├── SCGenericChart.h │ ├── SCGenericChart.m │ ├── SCLineChart.h │ ├── SCLineChart.m │ ├── SCPieChart.h │ ├── SCPieChart.m │ ├── SCPieChartDataItem.h │ ├── SCPieChartDataItem.m │ ├── SCTool.h │ ├── SCTool.m │ ├── UICountingLabel.h │ └── UICountingLabel.m ├── SCChartCell.h ├── SCChartCell.m ├── SCCircleCell.h ├── SCCircleCell.m ├── SCPieCell.h ├── SCPieCell.m ├── SCViewController.h ├── SCViewController.m └── main.m └── SCChartTests ├── Info.plist └── SCChartTests.m /.gitignore: -------------------------------------------------------------------------------- 1 | project.xcworkspace 2 | xcuserdata 3 | *.xccheckout 4 | config.plist 5 | *.swp 6 | .DS_Store 7 | Build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 如何使用-SCChart 2 | 3 | ![icon](https://img.alicdn.com/imgextra/i2/135480037/TB2E0ubkpXXXXaCXXXXXXXXXXXX_!!135480037.gif) 4 | 5 | ####导入主头文件 6 | #import "SCChart.h" 7 | 8 | ##### 一.折线图和柱状图 9 | 1.实例化 ( SCChartLineStyle | SCChartBarStyle ) 10 | 11 | SCChart *chartView = [[SCChart alloc] initwithSCChartDataFrame:CGRectMake(10, 10, [UIScreen mainScreen].bounds.size.width - 20, 150) withSource:self withStyle:SCChartLineStyle]; 12 | 13 | 2.设置横坐标标题 14 | 15 | - (NSArray *)SCChart_xLableArray:(SCChart *)chart { 16 | return 横坐标数组; 17 | } 18 | 19 | 3.设置数值(多重数组, 纵坐标标题动态计算) 20 | 21 | - (NSArray *)SCChart_yValueArray:(SCChart *)chart { 22 | return @[数组1,数组2]; 23 | } 24 | 25 | 4.设置折现颜色 26 | 27 | - (NSArray *)SCChart_ColorArray:(SCChart *)chart { 28 | return @[SCBlue,SCRed,SCGreen]; 29 | } 30 | 31 | 5.是否显示间隔线条(折线图专用) 32 | 33 | - (BOOL)SCChart:(SCChart *)chart ShowHorizonLineAtIndex:(NSInteger)index { 34 | return YES; 35 | } 36 | ##### 二.圆环图 37 | 1.实例化 38 | 39 | SCCircleChart *chartView = [[SCCircleChart alloc] initWithFrame:CGRectMake(0, (self.frame.size.height-100)/2, SCREEN_WIDTH, 100.0) total:@100 current:@60 clockwise:YES]; 40 | 41 | 2.设置圆环颜色 42 | 43 | [chartView setStrokeColor:SCBlue]; 44 | 45 | 3.画线 46 | 47 | [chartView strokeChart]; 48 | 49 | ##### 三.圆饼图 50 | 1.设置数值并实例化 51 | 52 | NSArray *items = @[[SCPieChartDataItem dataItemWithValue:10 color:SCRed description:@"A"], 53 | [SCPieChartDataItem dataItemWithValue:20 color:SCBlue description:@"B"], 54 | [SCPieChartDataItem dataItemWithValue:40 color:SCGreen description:@"C"], 55 | ]; 56 | 57 | SCPieChart *chartView = [[SCPieChart alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-150)/2, (self.frame.size.height-150)/2, 150.0, 150.0) items:items]; 58 | 59 | 2.设置描述文字 60 | 61 | chartView.descriptionTextColor = [UIColor whiteColor]; 62 | chartView.descriptionTextFont = [UIFont fontWithName:@"Avenir-Medium" size:12.0]; 63 | 64 | 3.画线 65 | 66 | [chartView strokeChart]; 67 | -------------------------------------------------------------------------------- /SCChart.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 250383A81AB2C9D80034BB22 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383A71AB2C9D80034BB22 /* main.m */; }; 11 | 250383AB1AB2C9D80034BB22 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383AA1AB2C9D80034BB22 /* AppDelegate.m */; }; 12 | 250383B31AB2C9D80034BB22 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 250383B21AB2C9D80034BB22 /* Images.xcassets */; }; 13 | 250383B61AB2C9D80034BB22 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 250383B41AB2C9D80034BB22 /* LaunchScreen.xib */; }; 14 | 250383C21AB2C9D80034BB22 /* SCChartTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383C11AB2C9D80034BB22 /* SCChartTests.m */; }; 15 | 250383CD1AB2CA300034BB22 /* SCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383CC1AB2CA300034BB22 /* SCViewController.m */; }; 16 | 250383F31AB2CAA50034BB22 /* SCBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383E61AB2CAA50034BB22 /* SCBar.m */; }; 17 | 250383F41AB2CAA50034BB22 /* SCBarChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383E81AB2CAA50034BB22 /* SCBarChart.m */; }; 18 | 250383F51AB2CAA50034BB22 /* SCChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383EA1AB2CAA50034BB22 /* SCChart.m */; }; 19 | 250383F61AB2CAA50034BB22 /* SCChartLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383EC1AB2CAA50034BB22 /* SCChartLabel.m */; }; 20 | 250383F71AB2CAA50034BB22 /* SCColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383EE1AB2CAA50034BB22 /* SCColor.m */; }; 21 | 250383F81AB2CAA50034BB22 /* SCLineChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383F01AB2CAA50034BB22 /* SCLineChart.m */; }; 22 | 250383F91AB2CAA50034BB22 /* SCTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383F21AB2CAA50034BB22 /* SCTool.m */; }; 23 | 250383FE1AB2CCFB0034BB22 /* SCBarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383FB1AB2CCFB0034BB22 /* SCBarCell.m */; }; 24 | 250383FF1AB2CCFB0034BB22 /* SCChartCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383FD1AB2CCFB0034BB22 /* SCChartCell.m */; }; 25 | 25FA1F3C1AC15F4300F4C43F /* SCCircleChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F3B1AC15F4300F4C43F /* SCCircleChart.m */; }; 26 | 25FA1F3F1AC15F4B00F4C43F /* UICountingLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F3E1AC15F4B00F4C43F /* UICountingLabel.m */; }; 27 | 25FA1F421AC161BF00F4C43F /* SCCircleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F411AC161BF00F4C43F /* SCCircleCell.m */; }; 28 | 25FA1F511AC1708800F4C43F /* SCPieChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F4E1AC1708800F4C43F /* SCPieChart.m */; }; 29 | 25FA1F521AC1708800F4C43F /* SCPieChartDataItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F501AC1708800F4C43F /* SCPieChartDataItem.m */; }; 30 | 25FA1F551AC170B200F4C43F /* SCPieCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F541AC170B200F4C43F /* SCPieCell.m */; }; 31 | 25FA1F581AC1718200F4C43F /* SCGenericChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F571AC1718200F4C43F /* SCGenericChart.m */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | 250383BC1AB2C9D80034BB22 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = 2503839A1AB2C9D80034BB22 /* Project object */; 38 | proxyType = 1; 39 | remoteGlobalIDString = 250383A11AB2C9D80034BB22; 40 | remoteInfo = SCChart; 41 | }; 42 | /* End PBXContainerItemProxy section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 250383A21AB2C9D80034BB22 /* SCChart.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SCChart.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 250383A61AB2C9D80034BB22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | 250383A71AB2C9D80034BB22 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | 250383A91AB2C9D80034BB22 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | 250383AA1AB2C9D80034BB22 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | 250383B21AB2C9D80034BB22 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 51 | 250383B51AB2C9D80034BB22 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 52 | 250383BB1AB2C9D80034BB22 /* SCChartTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCChartTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 250383C01AB2C9D80034BB22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 250383C11AB2C9D80034BB22 /* SCChartTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCChartTests.m; sourceTree = ""; }; 55 | 250383CB1AB2CA300034BB22 /* SCViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCViewController.h; sourceTree = ""; }; 56 | 250383CC1AB2CA300034BB22 /* SCViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCViewController.m; sourceTree = ""; }; 57 | 250383E51AB2CAA50034BB22 /* SCBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBar.h; sourceTree = ""; }; 58 | 250383E61AB2CAA50034BB22 /* SCBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBar.m; sourceTree = ""; }; 59 | 250383E71AB2CAA50034BB22 /* SCBarChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBarChart.h; sourceTree = ""; }; 60 | 250383E81AB2CAA50034BB22 /* SCBarChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBarChart.m; sourceTree = ""; }; 61 | 250383E91AB2CAA50034BB22 /* SCChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCChart.h; sourceTree = ""; }; 62 | 250383EA1AB2CAA50034BB22 /* SCChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCChart.m; sourceTree = ""; }; 63 | 250383EB1AB2CAA50034BB22 /* SCChartLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCChartLabel.h; sourceTree = ""; }; 64 | 250383EC1AB2CAA50034BB22 /* SCChartLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCChartLabel.m; sourceTree = ""; }; 65 | 250383ED1AB2CAA50034BB22 /* SCColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCColor.h; sourceTree = ""; }; 66 | 250383EE1AB2CAA50034BB22 /* SCColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCColor.m; sourceTree = ""; }; 67 | 250383EF1AB2CAA50034BB22 /* SCLineChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCLineChart.h; sourceTree = ""; }; 68 | 250383F01AB2CAA50034BB22 /* SCLineChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCLineChart.m; sourceTree = ""; }; 69 | 250383F11AB2CAA50034BB22 /* SCTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCTool.h; sourceTree = ""; }; 70 | 250383F21AB2CAA50034BB22 /* SCTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCTool.m; sourceTree = ""; }; 71 | 250383FA1AB2CCFB0034BB22 /* SCBarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBarCell.h; sourceTree = ""; }; 72 | 250383FB1AB2CCFB0034BB22 /* SCBarCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBarCell.m; sourceTree = ""; }; 73 | 250383FC1AB2CCFB0034BB22 /* SCChartCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCChartCell.h; sourceTree = ""; }; 74 | 250383FD1AB2CCFB0034BB22 /* SCChartCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCChartCell.m; sourceTree = ""; }; 75 | 25FA1F3A1AC15F4300F4C43F /* SCCircleChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCircleChart.h; sourceTree = ""; }; 76 | 25FA1F3B1AC15F4300F4C43F /* SCCircleChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCCircleChart.m; sourceTree = ""; }; 77 | 25FA1F3D1AC15F4B00F4C43F /* UICountingLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICountingLabel.h; sourceTree = ""; }; 78 | 25FA1F3E1AC15F4B00F4C43F /* UICountingLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICountingLabel.m; sourceTree = ""; }; 79 | 25FA1F401AC161BF00F4C43F /* SCCircleCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCircleCell.h; sourceTree = ""; }; 80 | 25FA1F411AC161BF00F4C43F /* SCCircleCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCCircleCell.m; sourceTree = ""; }; 81 | 25FA1F4D1AC1708800F4C43F /* SCPieChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieChart.h; sourceTree = ""; }; 82 | 25FA1F4E1AC1708800F4C43F /* SCPieChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieChart.m; sourceTree = ""; }; 83 | 25FA1F4F1AC1708800F4C43F /* SCPieChartDataItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieChartDataItem.h; sourceTree = ""; }; 84 | 25FA1F501AC1708800F4C43F /* SCPieChartDataItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieChartDataItem.m; sourceTree = ""; }; 85 | 25FA1F531AC170B200F4C43F /* SCPieCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieCell.h; sourceTree = ""; }; 86 | 25FA1F541AC170B200F4C43F /* SCPieCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieCell.m; sourceTree = ""; }; 87 | 25FA1F561AC1718200F4C43F /* SCGenericChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCGenericChart.h; sourceTree = ""; }; 88 | 25FA1F571AC1718200F4C43F /* SCGenericChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCGenericChart.m; sourceTree = ""; }; 89 | 25FA1F591AC1718E00F4C43F /* SCChartDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCChartDelegate.h; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 2503839F1AB2C9D80034BB22 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | 250383B81AB2C9D80034BB22 /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | 250383991AB2C9D80034BB22 = { 111 | isa = PBXGroup; 112 | children = ( 113 | 250383A41AB2C9D80034BB22 /* SCChart */, 114 | 250383BE1AB2C9D80034BB22 /* SCChartTests */, 115 | 250383A31AB2C9D80034BB22 /* Products */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 250383A31AB2C9D80034BB22 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 250383A21AB2C9D80034BB22 /* SCChart.app */, 123 | 250383BB1AB2C9D80034BB22 /* SCChartTests.xctest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | 250383A41AB2C9D80034BB22 /* SCChart */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 250383E41AB2CAA50034BB22 /* SCChart */, 132 | 250383A91AB2C9D80034BB22 /* AppDelegate.h */, 133 | 250383AA1AB2C9D80034BB22 /* AppDelegate.m */, 134 | 250383CB1AB2CA300034BB22 /* SCViewController.h */, 135 | 250383CC1AB2CA300034BB22 /* SCViewController.m */, 136 | 250383FC1AB2CCFB0034BB22 /* SCChartCell.h */, 137 | 250383FD1AB2CCFB0034BB22 /* SCChartCell.m */, 138 | 250383FA1AB2CCFB0034BB22 /* SCBarCell.h */, 139 | 250383FB1AB2CCFB0034BB22 /* SCBarCell.m */, 140 | 25FA1F401AC161BF00F4C43F /* SCCircleCell.h */, 141 | 25FA1F411AC161BF00F4C43F /* SCCircleCell.m */, 142 | 25FA1F531AC170B200F4C43F /* SCPieCell.h */, 143 | 25FA1F541AC170B200F4C43F /* SCPieCell.m */, 144 | 250383B21AB2C9D80034BB22 /* Images.xcassets */, 145 | 250383B41AB2C9D80034BB22 /* LaunchScreen.xib */, 146 | 250383A51AB2C9D80034BB22 /* Supporting Files */, 147 | ); 148 | path = SCChart; 149 | sourceTree = ""; 150 | }; 151 | 250383A51AB2C9D80034BB22 /* Supporting Files */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 250383A61AB2C9D80034BB22 /* Info.plist */, 155 | 250383A71AB2C9D80034BB22 /* main.m */, 156 | ); 157 | name = "Supporting Files"; 158 | sourceTree = ""; 159 | }; 160 | 250383BE1AB2C9D80034BB22 /* SCChartTests */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 250383C11AB2C9D80034BB22 /* SCChartTests.m */, 164 | 250383BF1AB2C9D80034BB22 /* Supporting Files */, 165 | ); 166 | path = SCChartTests; 167 | sourceTree = ""; 168 | }; 169 | 250383BF1AB2C9D80034BB22 /* Supporting Files */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 250383C01AB2C9D80034BB22 /* Info.plist */, 173 | ); 174 | name = "Supporting Files"; 175 | sourceTree = ""; 176 | }; 177 | 250383E41AB2CAA50034BB22 /* SCChart */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 250383E91AB2CAA50034BB22 /* SCChart.h */, 181 | 250383EA1AB2CAA50034BB22 /* SCChart.m */, 182 | 250383EF1AB2CAA50034BB22 /* SCLineChart.h */, 183 | 250383F01AB2CAA50034BB22 /* SCLineChart.m */, 184 | 250383E71AB2CAA50034BB22 /* SCBarChart.h */, 185 | 250383E81AB2CAA50034BB22 /* SCBarChart.m */, 186 | 25FA1F3A1AC15F4300F4C43F /* SCCircleChart.h */, 187 | 25FA1F3B1AC15F4300F4C43F /* SCCircleChart.m */, 188 | 25FA1F4D1AC1708800F4C43F /* SCPieChart.h */, 189 | 25FA1F4E1AC1708800F4C43F /* SCPieChart.m */, 190 | 250383E51AB2CAA50034BB22 /* SCBar.h */, 191 | 250383E61AB2CAA50034BB22 /* SCBar.m */, 192 | 250383EB1AB2CAA50034BB22 /* SCChartLabel.h */, 193 | 250383EC1AB2CAA50034BB22 /* SCChartLabel.m */, 194 | 250383ED1AB2CAA50034BB22 /* SCColor.h */, 195 | 250383EE1AB2CAA50034BB22 /* SCColor.m */, 196 | 250383F11AB2CAA50034BB22 /* SCTool.h */, 197 | 250383F21AB2CAA50034BB22 /* SCTool.m */, 198 | 25FA1F3D1AC15F4B00F4C43F /* UICountingLabel.h */, 199 | 25FA1F3E1AC15F4B00F4C43F /* UICountingLabel.m */, 200 | 25FA1F4F1AC1708800F4C43F /* SCPieChartDataItem.h */, 201 | 25FA1F501AC1708800F4C43F /* SCPieChartDataItem.m */, 202 | 25FA1F561AC1718200F4C43F /* SCGenericChart.h */, 203 | 25FA1F571AC1718200F4C43F /* SCGenericChart.m */, 204 | 25FA1F591AC1718E00F4C43F /* SCChartDelegate.h */, 205 | ); 206 | path = SCChart; 207 | sourceTree = ""; 208 | }; 209 | /* End PBXGroup section */ 210 | 211 | /* Begin PBXNativeTarget section */ 212 | 250383A11AB2C9D80034BB22 /* SCChart */ = { 213 | isa = PBXNativeTarget; 214 | buildConfigurationList = 250383C51AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChart" */; 215 | buildPhases = ( 216 | 2503839E1AB2C9D80034BB22 /* Sources */, 217 | 2503839F1AB2C9D80034BB22 /* Frameworks */, 218 | 250383A01AB2C9D80034BB22 /* Resources */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | ); 224 | name = SCChart; 225 | productName = SCChart; 226 | productReference = 250383A21AB2C9D80034BB22 /* SCChart.app */; 227 | productType = "com.apple.product-type.application"; 228 | }; 229 | 250383BA1AB2C9D80034BB22 /* SCChartTests */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = 250383C81AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChartTests" */; 232 | buildPhases = ( 233 | 250383B71AB2C9D80034BB22 /* Sources */, 234 | 250383B81AB2C9D80034BB22 /* Frameworks */, 235 | 250383B91AB2C9D80034BB22 /* Resources */, 236 | ); 237 | buildRules = ( 238 | ); 239 | dependencies = ( 240 | 250383BD1AB2C9D80034BB22 /* PBXTargetDependency */, 241 | ); 242 | name = SCChartTests; 243 | productName = SCChartTests; 244 | productReference = 250383BB1AB2C9D80034BB22 /* SCChartTests.xctest */; 245 | productType = "com.apple.product-type.bundle.unit-test"; 246 | }; 247 | /* End PBXNativeTarget section */ 248 | 249 | /* Begin PBXProject section */ 250 | 2503839A1AB2C9D80034BB22 /* Project object */ = { 251 | isa = PBXProject; 252 | attributes = { 253 | CLASSPREFIX = SC; 254 | LastUpgradeCheck = 0610; 255 | ORGANIZATIONNAME = meilishuo; 256 | TargetAttributes = { 257 | 250383A11AB2C9D80034BB22 = { 258 | CreatedOnToolsVersion = 6.1; 259 | }; 260 | 250383BA1AB2C9D80034BB22 = { 261 | CreatedOnToolsVersion = 6.1; 262 | TestTargetID = 250383A11AB2C9D80034BB22; 263 | }; 264 | }; 265 | }; 266 | buildConfigurationList = 2503839D1AB2C9D80034BB22 /* Build configuration list for PBXProject "SCChart" */; 267 | compatibilityVersion = "Xcode 3.2"; 268 | developmentRegion = English; 269 | hasScannedForEncodings = 0; 270 | knownRegions = ( 271 | en, 272 | Base, 273 | ); 274 | mainGroup = 250383991AB2C9D80034BB22; 275 | productRefGroup = 250383A31AB2C9D80034BB22 /* Products */; 276 | projectDirPath = ""; 277 | projectRoot = ""; 278 | targets = ( 279 | 250383A11AB2C9D80034BB22 /* SCChart */, 280 | 250383BA1AB2C9D80034BB22 /* SCChartTests */, 281 | ); 282 | }; 283 | /* End PBXProject section */ 284 | 285 | /* Begin PBXResourcesBuildPhase section */ 286 | 250383A01AB2C9D80034BB22 /* Resources */ = { 287 | isa = PBXResourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | 250383B61AB2C9D80034BB22 /* LaunchScreen.xib in Resources */, 291 | 250383B31AB2C9D80034BB22 /* Images.xcassets in Resources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | 250383B91AB2C9D80034BB22 /* Resources */ = { 296 | isa = PBXResourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | /* End PBXResourcesBuildPhase section */ 303 | 304 | /* Begin PBXSourcesBuildPhase section */ 305 | 2503839E1AB2C9D80034BB22 /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | 250383F61AB2CAA50034BB22 /* SCChartLabel.m in Sources */, 310 | 250383FF1AB2CCFB0034BB22 /* SCChartCell.m in Sources */, 311 | 250383F91AB2CAA50034BB22 /* SCTool.m in Sources */, 312 | 25FA1F3F1AC15F4B00F4C43F /* UICountingLabel.m in Sources */, 313 | 25FA1F421AC161BF00F4C43F /* SCCircleCell.m in Sources */, 314 | 25FA1F511AC1708800F4C43F /* SCPieChart.m in Sources */, 315 | 25FA1F521AC1708800F4C43F /* SCPieChartDataItem.m in Sources */, 316 | 250383FE1AB2CCFB0034BB22 /* SCBarCell.m in Sources */, 317 | 250383F71AB2CAA50034BB22 /* SCColor.m in Sources */, 318 | 250383AB1AB2C9D80034BB22 /* AppDelegate.m in Sources */, 319 | 250383F41AB2CAA50034BB22 /* SCBarChart.m in Sources */, 320 | 250383F31AB2CAA50034BB22 /* SCBar.m in Sources */, 321 | 250383F81AB2CAA50034BB22 /* SCLineChart.m in Sources */, 322 | 25FA1F3C1AC15F4300F4C43F /* SCCircleChart.m in Sources */, 323 | 250383CD1AB2CA300034BB22 /* SCViewController.m in Sources */, 324 | 250383F51AB2CAA50034BB22 /* SCChart.m in Sources */, 325 | 25FA1F551AC170B200F4C43F /* SCPieCell.m in Sources */, 326 | 25FA1F581AC1718200F4C43F /* SCGenericChart.m in Sources */, 327 | 250383A81AB2C9D80034BB22 /* main.m in Sources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | 250383B71AB2C9D80034BB22 /* Sources */ = { 332 | isa = PBXSourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | 250383C21AB2C9D80034BB22 /* SCChartTests.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | /* End PBXSourcesBuildPhase section */ 340 | 341 | /* Begin PBXTargetDependency section */ 342 | 250383BD1AB2C9D80034BB22 /* PBXTargetDependency */ = { 343 | isa = PBXTargetDependency; 344 | target = 250383A11AB2C9D80034BB22 /* SCChart */; 345 | targetProxy = 250383BC1AB2C9D80034BB22 /* PBXContainerItemProxy */; 346 | }; 347 | /* End PBXTargetDependency section */ 348 | 349 | /* Begin PBXVariantGroup section */ 350 | 250383B41AB2C9D80034BB22 /* LaunchScreen.xib */ = { 351 | isa = PBXVariantGroup; 352 | children = ( 353 | 250383B51AB2C9D80034BB22 /* Base */, 354 | ); 355 | name = LaunchScreen.xib; 356 | sourceTree = ""; 357 | }; 358 | /* End PBXVariantGroup section */ 359 | 360 | /* Begin XCBuildConfiguration section */ 361 | 250383C31AB2C9D80034BB22 /* Debug */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_MODULES = YES; 368 | CLANG_ENABLE_OBJC_ARC = YES; 369 | CLANG_WARN_BOOL_CONVERSION = YES; 370 | CLANG_WARN_CONSTANT_CONVERSION = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INT_CONVERSION = YES; 375 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 376 | CLANG_WARN_UNREACHABLE_CODE = YES; 377 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 378 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 379 | COPY_PHASE_STRIP = NO; 380 | ENABLE_STRICT_OBJC_MSGSEND = YES; 381 | GCC_C_LANGUAGE_STANDARD = gnu99; 382 | GCC_DYNAMIC_NO_PIC = NO; 383 | GCC_OPTIMIZATION_LEVEL = 0; 384 | GCC_PREPROCESSOR_DEFINITIONS = ( 385 | "DEBUG=1", 386 | "$(inherited)", 387 | ); 388 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 389 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 390 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 391 | GCC_WARN_UNDECLARED_SELECTOR = YES; 392 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 393 | GCC_WARN_UNUSED_FUNCTION = YES; 394 | GCC_WARN_UNUSED_VARIABLE = YES; 395 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 396 | MTL_ENABLE_DEBUG_INFO = YES; 397 | ONLY_ACTIVE_ARCH = YES; 398 | SDKROOT = iphoneos; 399 | TARGETED_DEVICE_FAMILY = "1,2"; 400 | }; 401 | name = Debug; 402 | }; 403 | 250383C41AB2C9D80034BB22 /* Release */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ALWAYS_SEARCH_USER_PATHS = NO; 407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 408 | CLANG_CXX_LIBRARY = "libc++"; 409 | CLANG_ENABLE_MODULES = YES; 410 | CLANG_ENABLE_OBJC_ARC = YES; 411 | CLANG_WARN_BOOL_CONVERSION = YES; 412 | CLANG_WARN_CONSTANT_CONVERSION = YES; 413 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 414 | CLANG_WARN_EMPTY_BODY = YES; 415 | CLANG_WARN_ENUM_CONVERSION = YES; 416 | CLANG_WARN_INT_CONVERSION = YES; 417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 418 | CLANG_WARN_UNREACHABLE_CODE = YES; 419 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 420 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 421 | COPY_PHASE_STRIP = YES; 422 | ENABLE_NS_ASSERTIONS = NO; 423 | ENABLE_STRICT_OBJC_MSGSEND = YES; 424 | GCC_C_LANGUAGE_STANDARD = gnu99; 425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 426 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 427 | GCC_WARN_UNDECLARED_SELECTOR = YES; 428 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 429 | GCC_WARN_UNUSED_FUNCTION = YES; 430 | GCC_WARN_UNUSED_VARIABLE = YES; 431 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 432 | MTL_ENABLE_DEBUG_INFO = NO; 433 | SDKROOT = iphoneos; 434 | TARGETED_DEVICE_FAMILY = "1,2"; 435 | VALIDATE_PRODUCT = YES; 436 | }; 437 | name = Release; 438 | }; 439 | 250383C61AB2C9D80034BB22 /* Debug */ = { 440 | isa = XCBuildConfiguration; 441 | buildSettings = { 442 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 443 | INFOPLIST_FILE = SCChart/Info.plist; 444 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 445 | PRODUCT_NAME = "$(TARGET_NAME)"; 446 | }; 447 | name = Debug; 448 | }; 449 | 250383C71AB2C9D80034BB22 /* Release */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 453 | INFOPLIST_FILE = SCChart/Info.plist; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | }; 457 | name = Release; 458 | }; 459 | 250383C91AB2C9D80034BB22 /* Debug */ = { 460 | isa = XCBuildConfiguration; 461 | buildSettings = { 462 | BUNDLE_LOADER = "$(TEST_HOST)"; 463 | FRAMEWORK_SEARCH_PATHS = ( 464 | "$(SDKROOT)/Developer/Library/Frameworks", 465 | "$(inherited)", 466 | ); 467 | GCC_PREPROCESSOR_DEFINITIONS = ( 468 | "DEBUG=1", 469 | "$(inherited)", 470 | ); 471 | INFOPLIST_FILE = SCChartTests/Info.plist; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 473 | PRODUCT_NAME = "$(TARGET_NAME)"; 474 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SCChart.app/SCChart"; 475 | }; 476 | name = Debug; 477 | }; 478 | 250383CA1AB2C9D80034BB22 /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | BUNDLE_LOADER = "$(TEST_HOST)"; 482 | FRAMEWORK_SEARCH_PATHS = ( 483 | "$(SDKROOT)/Developer/Library/Frameworks", 484 | "$(inherited)", 485 | ); 486 | INFOPLIST_FILE = SCChartTests/Info.plist; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SCChart.app/SCChart"; 490 | }; 491 | name = Release; 492 | }; 493 | /* End XCBuildConfiguration section */ 494 | 495 | /* Begin XCConfigurationList section */ 496 | 2503839D1AB2C9D80034BB22 /* Build configuration list for PBXProject "SCChart" */ = { 497 | isa = XCConfigurationList; 498 | buildConfigurations = ( 499 | 250383C31AB2C9D80034BB22 /* Debug */, 500 | 250383C41AB2C9D80034BB22 /* Release */, 501 | ); 502 | defaultConfigurationIsVisible = 0; 503 | defaultConfigurationName = Release; 504 | }; 505 | 250383C51AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChart" */ = { 506 | isa = XCConfigurationList; 507 | buildConfigurations = ( 508 | 250383C61AB2C9D80034BB22 /* Debug */, 509 | 250383C71AB2C9D80034BB22 /* Release */, 510 | ); 511 | defaultConfigurationIsVisible = 0; 512 | defaultConfigurationName = Release; 513 | }; 514 | 250383C81AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChartTests" */ = { 515 | isa = XCConfigurationList; 516 | buildConfigurations = ( 517 | 250383C91AB2C9D80034BB22 /* Debug */, 518 | 250383CA1AB2C9D80034BB22 /* Release */, 519 | ); 520 | defaultConfigurationIsVisible = 0; 521 | defaultConfigurationName = Release; 522 | }; 523 | /* End XCConfigurationList section */ 524 | }; 525 | rootObject = 2503839A1AB2C9D80034BB22 /* Project object */; 526 | } 527 | -------------------------------------------------------------------------------- /SCChart.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SCChart.xcodeproj/xcuserdata/MLS.xcuserdatad/xcschemes/SCChart.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /SCChart.xcodeproj/xcuserdata/MLS.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SCChart.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 250383A11AB2C9D80034BB22 16 | 17 | primary 18 | 19 | 20 | 250383BA1AB2C9D80034BB22 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SCChart/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /SCChart/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "SCViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 21 | self.window.rootViewController = [[SCViewController alloc] init]; 22 | [self.window makeKeyAndVisible]; 23 | return YES; 24 | } 25 | 26 | - (void)applicationWillResignActive:(UIApplication *)application { 27 | // 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. 28 | // 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. 29 | } 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application { 32 | // 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. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | - (void)applicationDidBecomeActive:(UIApplication *)application { 41 | // 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. 42 | } 43 | 44 | - (void)applicationWillTerminate:(UIApplication *)application { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /SCChart/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SCChart/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /SCChart/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.meilishuo.bizfe.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SCChart/SCBarCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCBarCell.h 3 | // UUChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCBarCell : UITableViewCell 12 | 13 | - (void)configUI:(NSIndexPath *)indexPath; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SCChart/SCBarCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCBarCell.m 3 | // UUChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCBarCell.h" 10 | #import "SCChart.h" 11 | 12 | @interface SCBarCell () 13 | { 14 | NSIndexPath *path; 15 | SCChart *chartView; 16 | } 17 | @end 18 | 19 | @implementation SCBarCell 20 | 21 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 22 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 23 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 24 | [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; 25 | btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; 26 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 27 | btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); 28 | [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; 29 | [self addSubview:btn]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)btnPressed:(id)sender { 35 | [chartView strokeChart]; 36 | } 37 | 38 | - (void)configUI:(NSIndexPath *)indexPath { 39 | if (chartView) { 40 | [chartView removeFromSuperview]; 41 | chartView = nil; 42 | } 43 | path = indexPath; 44 | chartView = [[SCChart alloc] initwithSCChartDataFrame:CGRectMake(10, (self.frame.size.height-150)/2, [UIScreen mainScreen].bounds.size.width - 20, 150) 45 | withSource:self 46 | withStyle:SCChartBarStyle]; 47 | [chartView showInView:self.contentView]; 48 | } 49 | 50 | - (NSArray *)getXTitles:(int)num { 51 | NSMutableArray *xTitles = [NSMutableArray array]; 52 | for (int i=0; i 10 | 11 | @interface SCBar : UIView 12 | 13 | @property (nonatomic) float grade; 14 | 15 | @property (nonatomic,strong) CAShapeLayer * chartLine; 16 | 17 | @property (nonatomic, strong) UIColor * barColor; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // UUBar.m 3 | // UUChartDemo 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCBar.h" 10 | #import "SCColor.h" 11 | 12 | @implementation SCBar 13 | 14 | - (id)initWithFrame:(CGRect)frame 15 | { 16 | self = [super initWithFrame:frame]; 17 | if (self) { 18 | // Initialization code 19 | _chartLine = [CAShapeLayer layer]; 20 | _chartLine.lineCap = kCALineCapSquare; 21 | _chartLine.fillColor = [[UIColor whiteColor] CGColor]; 22 | _chartLine.lineWidth = self.frame.size.width; 23 | _chartLine.strokeEnd = 0.0; 24 | self.clipsToBounds = YES; 25 | [self.layer addSublayer:_chartLine]; 26 | 27 | // self.layer.cornerRadius = 2.0; // 直接设置layer会造成卡顿 28 | } 29 | return self; 30 | } 31 | 32 | -(void)setGrade:(float)grade 33 | { 34 | if (grade==0) 35 | return; 36 | 37 | _grade = grade; 38 | UIBezierPath *progressline = [UIBezierPath bezierPath]; 39 | 40 | [progressline moveToPoint:CGPointMake(self.frame.size.width/2.0, self.frame.size.height+30)]; 41 | [progressline addLineToPoint:CGPointMake(self.frame.size.width/2.0, (1 - grade) * self.frame.size.height+15)]; 42 | 43 | [progressline setLineWidth:1.0]; 44 | [progressline setLineCapStyle:kCGLineCapSquare]; 45 | _chartLine.path = progressline.CGPath; 46 | 47 | if (_barColor) { 48 | _chartLine.strokeColor = [_barColor CGColor]; 49 | }else{ 50 | _chartLine.strokeColor = [SCGreen CGColor]; 51 | } 52 | 53 | CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 54 | pathAnimation.duration = 1.5; 55 | pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 56 | pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; 57 | pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; 58 | pathAnimation.autoreverses = NO; 59 | [_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 60 | 61 | _chartLine.strokeEnd = 2.0; 62 | } 63 | 64 | - (void)drawRect:(CGRect)rect 65 | { 66 | //Draw BG 67 | CGContextRef context = UIGraphicsGetCurrentContext(); 68 | 69 | CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); 70 | CGContextFillRect(context, rect); 71 | 72 | } 73 | 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCBarChart.h: -------------------------------------------------------------------------------- 1 | // 2 | // UUBarChart.h 3 | // UUChartDemo 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SCColor.h" 11 | #define chartMargin 10 12 | #define xLabelMargin 15 13 | #define yLabelMargin 15 14 | #define UULabelHeight 10 15 | #define UUYLabelwidth 30 16 | 17 | @interface SCBarChart : UIView 18 | 19 | /** 20 | * This method will call and troke the line in animation 21 | */ 22 | 23 | -(void)strokeChart; 24 | 25 | @property (strong, nonatomic) NSArray * xLabels; 26 | 27 | @property (strong, nonatomic) NSArray * yLabels; 28 | 29 | @property (strong, nonatomic) NSArray * yValues; 30 | 31 | @property (nonatomic) CGFloat xLabelWidth; 32 | 33 | @property (nonatomic) float yValueMax; 34 | @property (nonatomic) float yValueMin; 35 | 36 | @property (nonatomic, assign) BOOL showRange; 37 | 38 | @property (nonatomic, assign) CGRange chooseRange; 39 | 40 | @property (nonatomic, strong) NSArray * colors; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCBarChart.m: -------------------------------------------------------------------------------- 1 | // 2 | // UUBarChart.m 3 | // UUChartDemo 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCBarChart.h" 10 | #import "SCChartLabel.h" 11 | #import "SCBar.h" 12 | #import "SCTool.h" 13 | 14 | @interface SCBarChart () 15 | { 16 | UIScrollView *myScrollView; 17 | } 18 | @end 19 | 20 | @implementation SCBarChart 21 | 22 | - (id)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | // Initialization code 27 | self.clipsToBounds = YES; 28 | myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(UUYLabelwidth, 0, frame.size.width-UUYLabelwidth, frame.size.height)]; 29 | [self addSubview:myScrollView]; 30 | } 31 | return self; 32 | } 33 | 34 | -(void)setYValues:(NSArray *)yValues 35 | { 36 | _yValues = yValues; 37 | [self setYLabels:yValues]; 38 | } 39 | 40 | -(void)setYLabels:(NSArray *)yLabels 41 | { 42 | CGFloat max = 0; 43 | CGFloat min = 1000000000; 44 | NSInteger rowCount = 0; // 自动计算每个图表适合的行数 45 | for (NSArray * ary in yLabels) { 46 | for (NSString *valueString in ary) { 47 | CGFloat value = [valueString floatValue]; 48 | if (value > max) { 49 | max = value; 50 | } 51 | if (value < min) { 52 | min = value; 53 | } 54 | } 55 | } 56 | if (self.showRange) { 57 | _yValueMin = min; 58 | }else{ 59 | _yValueMin = 0; 60 | } 61 | _yValueMax = max; 62 | 63 | if (_chooseRange.max!=_chooseRange.min) { // 自定义数值范围 64 | _yValueMax = _chooseRange.max; 65 | _yValueMin = _chooseRange.min; 66 | } else { // 自动计算数值范围和合适的行数 67 | rowCount = [SCTool rowCountWithValueMax:_yValueMax] == 0 ? 5 : [SCTool rowCountWithValueMax:_yValueMax]; 68 | _yValueMax = [SCTool rangeMaxWithValueMax:_yValueMax] == 0 ? 100 : [SCTool rangeMaxWithValueMax:_yValueMax]; 69 | _yValueMin = 0; 70 | } 71 | 72 | float level = (_yValueMax-_yValueMin) /rowCount; // 每个区间的差值 73 | CGFloat chartCavanHeight = self.frame.size.height - UULabelHeight*3; 74 | CGFloat levelHeight = chartCavanHeight /rowCount; // 每个区间的高度 75 | 76 | for (int i=0; i=8) { 89 | num = 8; 90 | }else if (xLabels.count<=4){ 91 | num = 4; 92 | }else{ 93 | num = xLabels.count; 94 | } 95 | _xLabelWidth = myScrollView.frame.size.width/num; 96 | 97 | for (int i=0; i 10 | #import "SCChart.h" 11 | #import "SCColor.h" 12 | #import "SCLineChart.h" 13 | #import "SCBarChart.h" 14 | #import "SCCircleChart.h" 15 | #import "SCPieChart.h" 16 | //类型 17 | typedef enum { 18 | SCChartLineStyle, 19 | SCChartBarStyle 20 | } SCChartStyle; 21 | 22 | 23 | @class SCChart; 24 | @protocol SCChartDataSource 25 | 26 | @required 27 | //横坐标标题数组 28 | - (NSArray *)SCChart_xLableArray:(SCChart *)chart; 29 | 30 | //数值多重数组 31 | - (NSArray *)SCChart_yValueArray:(SCChart *)chart; 32 | 33 | @optional 34 | //颜色数组 35 | - (NSArray *)SCChart_ColorArray:(SCChart *)chart; 36 | 37 | //显示数值范围 38 | - (CGRange)SCChartChooseRangeInLineChart:(SCChart *)chart; 39 | 40 | #pragma mark 折线图专享功能 41 | //标记数值区域 42 | - (CGRange)SCChartMarkRangeInLineChart:(SCChart *)chart; 43 | 44 | //判断显示横线条 45 | - (BOOL)SCChart:(SCChart *)chart ShowHorizonLineAtIndex:(NSInteger)index; 46 | 47 | //判断显示最大最小值 48 | - (BOOL)SCChart:(SCChart *)chart ShowMaxMinAtIndex:(NSInteger)index; 49 | @end 50 | 51 | 52 | @interface SCChart : UIView 53 | 54 | //是否自动显示范围 55 | @property (nonatomic, assign) BOOL showRange; 56 | 57 | @property (assign) SCChartStyle chartStyle; 58 | 59 | -(id)initwithSCChartDataFrame:(CGRect)rect withSource:(id)dataSource withStyle:(SCChartStyle)style; 60 | 61 | - (void)showInView:(UIView *)view; 62 | 63 | -(void)strokeChart; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCChart.m: -------------------------------------------------------------------------------- 1 | // 2 | // UUChart.m 3 | // UUChart 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCChart.h" 10 | #define kRowMax 6 // 可支持最大行数 11 | 12 | @interface SCChart () 13 | 14 | @property (strong, nonatomic) SCLineChart * lineChart; 15 | 16 | @property (strong, nonatomic) SCBarChart * barChart; 17 | 18 | @property (assign, nonatomic) id dataSource; 19 | 20 | @end 21 | 22 | @implementation SCChart 23 | 24 | -(id)initwithSCChartDataFrame:(CGRect)rect withSource:(id)dataSource withStyle:(SCChartStyle)style{ 25 | self.dataSource = dataSource; 26 | self.chartStyle = style; 27 | return [self initWithFrame:rect]; 28 | } 29 | 30 | - (id)initWithFrame:(CGRect)frame 31 | { 32 | self = [super initWithFrame:frame]; 33 | if (self) { 34 | // Initialization code 35 | self.backgroundColor = [UIColor whiteColor]; 36 | self.clipsToBounds = NO; 37 | } 38 | return self; 39 | } 40 | 41 | -(void)setUpChart{ 42 | if (self.chartStyle == SCChartLineStyle) { 43 | 44 | [self.lineChart removeFromSuperview]; 45 | self.lineChart = nil; 46 | 47 | if(!_lineChart){ 48 | _lineChart = [[SCLineChart alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 49 | [self addSubview:_lineChart]; 50 | } 51 | //选择标记范围 52 | if ([self.dataSource respondsToSelector:@selector(SCChartMarkRangeInLineChart:)]) { 53 | [_lineChart setMarkRange:[self.dataSource SCChartMarkRangeInLineChart:self]]; 54 | } 55 | //选择显示范围 56 | if ([self.dataSource respondsToSelector:@selector(SCChartChooseRangeInLineChart:)]) { 57 | [_lineChart setChooseRange:[self.dataSource SCChartChooseRangeInLineChart:self]]; 58 | } 59 | //显示颜色 60 | if ([self.dataSource respondsToSelector:@selector(SCChart_ColorArray:)]) { 61 | [_lineChart setColors:[self.dataSource SCChart_ColorArray:self]]; 62 | } 63 | //显示横线 64 | if ([self.dataSource respondsToSelector:@selector(SCChart:ShowHorizonLineAtIndex:)]) { 65 | NSMutableArray *showHorizonArray = [[NSMutableArray alloc]init]; 66 | for (int i=0; i0){ 81 | for (int i=0; i 10 | 11 | @protocol SCChartDelegate 12 | @optional 13 | /** 14 | * Callback method that gets invoked when the user taps on the chart line. 15 | */ 16 | - (void)userClickedOnLinePoint:(CGPoint)point lineIndex:(NSInteger)lineIndex; 17 | 18 | /** 19 | * Callback method that gets invoked when the user taps on a chart line key point. 20 | */ 21 | - (void)userClickedOnLineKeyPoint:(CGPoint)point 22 | lineIndex:(NSInteger)lineIndex 23 | pointIndex:(NSInteger)pointIndex; 24 | 25 | /** 26 | * Callback method that gets invoked when the user taps on a chart bar. 27 | */ 28 | - (void)userClickedOnBarAtIndex:(NSInteger)barIndex; 29 | 30 | 31 | - (void)userClickedOnPieIndexItem:(NSInteger)pieIndex; 32 | - (void)didUnselectPieItem; 33 | @end 34 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCChartLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // PNChartLabel.h 3 | // PNChart 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCChartLabel : UILabel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCChartLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // PNChartLabel.m 3 | // PNChart 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCChartLabel.h" 10 | #import "SCColor.h" 11 | 12 | @implementation SCChartLabel 13 | 14 | - (id)initWithFrame:(CGRect)frame 15 | { 16 | self = [super initWithFrame:frame]; 17 | if (self) { 18 | // Initialization code 19 | [self setLineBreakMode:NSLineBreakByWordWrapping]; 20 | [self setMinimumScaleFactor:5.0f]; 21 | [self setNumberOfLines:1]; 22 | [self setFont:[UIFont boldSystemFontOfSize:9.0f]]; 23 | [self setTextColor: SCDeepGrey]; 24 | self.backgroundColor = [UIColor clearColor]; 25 | [self setTextAlignment:NSTextAlignmentCenter]; 26 | self.userInteractionEnabled = YES; 27 | } 28 | return self; 29 | } 30 | 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCCircleChart.h: -------------------------------------------------------------------------------- 1 | // 2 | // PNCircleChart.h 3 | // PNChartDemo 4 | // 5 | // Created by kevinzhow on 13-11-30. 6 | // Copyright (c) 2013年 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SCColor.h" 11 | #import "UICountingLabel.h" 12 | 13 | typedef NS_ENUM (NSUInteger, SCChartFormatType) { 14 | SCChartFormatTypePercent, 15 | SCChartFormatTypeDollar, 16 | SCChartFormatTypeNone 17 | }; 18 | 19 | #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) 20 | 21 | @interface SCCircleChart : UIView 22 | 23 | - (void)strokeChart; 24 | - (void)growChartByAmount:(NSNumber *)growAmount; 25 | - (void)updateChartByCurrent:(NSNumber *)current; 26 | - (void)updateChartByCurrent:(NSNumber *)current byTotal:(NSNumber *)total; 27 | - (id)initWithFrame:(CGRect)frame 28 | total:(NSNumber *)total 29 | current:(NSNumber *)current 30 | clockwise:(BOOL)clockwise; 31 | 32 | - (id)initWithFrame:(CGRect)frame 33 | total:(NSNumber *)total 34 | current:(NSNumber *)current 35 | clockwise:(BOOL)clockwise 36 | shadow:(BOOL)hasBackgroundShadow 37 | shadowColor:(UIColor *)backgroundShadowColor; 38 | 39 | - (id)initWithFrame:(CGRect)frame 40 | total:(NSNumber *)total 41 | current:(NSNumber *)current 42 | clockwise:(BOOL)clockwise 43 | shadow:(BOOL)hasBackgroundShadow 44 | shadowColor:(UIColor *)backgroundShadowColor 45 | displayCountingLabel:(BOOL)displayCountingLabel; 46 | 47 | - (id)initWithFrame:(CGRect)frame 48 | total:(NSNumber *)total 49 | current:(NSNumber *)current 50 | clockwise:(BOOL)clockwise 51 | shadow:(BOOL)hasBackgroundShadow 52 | shadowColor:(UIColor *)backgroundShadowColor 53 | displayCountingLabel:(BOOL)displayCountingLabel 54 | overrideLineWidth:(NSNumber *)overrideLineWidth; 55 | 56 | @property (strong, nonatomic) UICountingLabel *countingLabel; 57 | @property (nonatomic) UIColor *strokeColor; 58 | @property (nonatomic) UIColor *strokeColorGradientStart; 59 | @property (nonatomic) NSNumber *total; 60 | @property (nonatomic) NSNumber *current; 61 | @property (nonatomic) NSNumber *lineWidth; 62 | @property (nonatomic) NSTimeInterval duration; 63 | @property (nonatomic) SCChartFormatType chartType; 64 | @property (nonatomic, copy) NSString *format; 65 | 66 | 67 | @property (nonatomic) CAShapeLayer *circle; 68 | @property (nonatomic) CAShapeLayer *gradientMask; 69 | @property (nonatomic) CAShapeLayer *circleBackground; 70 | 71 | @property (nonatomic) BOOL displayCountingLabel; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCCircleChart.m: -------------------------------------------------------------------------------- 1 | // 2 | // PNCircleChart.m 3 | // PNChartDemo 4 | // 5 | // Created by kevinzhow on 13-11-30. 6 | // Copyright (c) 2013年 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import "SCCircleChart.h" 10 | 11 | @interface SCCircleChart () 12 | @end 13 | 14 | @implementation SCCircleChart 15 | 16 | - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise { 17 | 18 | return [self initWithFrame:frame 19 | total:total 20 | current:current 21 | clockwise:clockwise 22 | shadow:NO 23 | shadowColor:[UIColor clearColor] 24 | displayCountingLabel:YES 25 | overrideLineWidth:@3.0f]; 26 | 27 | } 28 | 29 | - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor { 30 | 31 | return [self initWithFrame:frame 32 | total:total 33 | current:current 34 | clockwise:clockwise 35 | shadow:shadow 36 | shadowColor:backgroundShadowColor 37 | displayCountingLabel:YES 38 | overrideLineWidth:@3.0f]; 39 | 40 | } 41 | 42 | - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor displayCountingLabel:(BOOL)displayCountingLabel { 43 | 44 | return [self initWithFrame:frame 45 | total:total 46 | current:current 47 | clockwise:clockwise 48 | shadow:shadow 49 | shadowColor:SCGreen 50 | displayCountingLabel:displayCountingLabel 51 | overrideLineWidth:@3.0f]; 52 | 53 | } 54 | 55 | - (id)initWithFrame:(CGRect)frame 56 | total:(NSNumber *)total 57 | current:(NSNumber *)current 58 | clockwise:(BOOL)clockwise 59 | shadow:(BOOL)hasBackgroundShadow 60 | shadowColor:(UIColor *)backgroundShadowColor 61 | displayCountingLabel:(BOOL)displayCountingLabel 62 | overrideLineWidth:(NSNumber *)overrideLineWidth 63 | { 64 | self = [super initWithFrame:frame]; 65 | 66 | if (self) { 67 | _total = total; 68 | _current = current; 69 | _strokeColor = SCFreshGreen; 70 | _duration = 1.0; 71 | _chartType = SCChartFormatTypePercent; 72 | 73 | _displayCountingLabel = displayCountingLabel; 74 | 75 | CGFloat startAngle = clockwise ? -90.0f : 270.0f; 76 | CGFloat endAngle = clockwise ? -90.01f : 270.01f; 77 | 78 | _lineWidth = overrideLineWidth; 79 | 80 | UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2.0f, self.frame.size.height/2.0f) 81 | radius:(self.frame.size.height * 0.5) - ([_lineWidth floatValue]/2.0f) 82 | startAngle:DEGREES_TO_RADIANS(startAngle) 83 | endAngle:DEGREES_TO_RADIANS(endAngle) 84 | clockwise:clockwise]; 85 | 86 | _circle = [CAShapeLayer layer]; 87 | _circle.path = circlePath.CGPath; 88 | _circle.lineCap = kCALineCapRound; 89 | _circle.fillColor = [UIColor clearColor].CGColor; 90 | _circle.lineWidth = [_lineWidth floatValue]; 91 | _circle.zPosition = 1; 92 | 93 | _circleBackground = [CAShapeLayer layer]; 94 | _circleBackground.path = circlePath.CGPath; 95 | _circleBackground.lineCap = kCALineCapRound; 96 | _circleBackground.fillColor = [UIColor clearColor].CGColor; 97 | _circleBackground.lineWidth = [_lineWidth floatValue]; 98 | _circleBackground.strokeColor = (hasBackgroundShadow ? backgroundShadowColor.CGColor : [UIColor clearColor].CGColor); 99 | _circleBackground.strokeEnd = 1.0; 100 | _circleBackground.zPosition = -1; 101 | 102 | [self.layer addSublayer:_circle]; 103 | [self.layer addSublayer:_circleBackground]; 104 | 105 | _countingLabel = [[UICountingLabel alloc] initWithFrame:CGRectMake(0, 0, 100.0, 50.0)]; 106 | [_countingLabel setTextAlignment:NSTextAlignmentCenter]; 107 | [_countingLabel setFont:[UIFont boldSystemFontOfSize:12.0f]]; 108 | [_countingLabel setTextColor:[UIColor grayColor]]; 109 | [_countingLabel setBackgroundColor:[UIColor clearColor]]; 110 | [_countingLabel setCenter:CGPointMake(self.frame.size.width/2.0f, self.frame.size.height/2.0f)]; 111 | _countingLabel.numberOfLines = 0; 112 | _countingLabel.method = UILabelCountingMethodEaseInOut; 113 | if (_displayCountingLabel) { 114 | [self addSubview:_countingLabel]; 115 | } 116 | } 117 | 118 | return self; 119 | } 120 | 121 | 122 | - (void)strokeChart 123 | { 124 | // Add counting label 125 | 126 | if (_displayCountingLabel) { 127 | switch (self.chartType) { 128 | case SCChartFormatTypePercent: 129 | self.format = @"%d%%"; 130 | break; 131 | case SCChartFormatTypeDollar: 132 | self.format = @"$%d"; 133 | break; 134 | case SCChartFormatTypeNone: 135 | default: 136 | self.format = self.format ? self.format : @"%d"; 137 | break; 138 | } 139 | self.countingLabel.format = self.format; 140 | [self addSubview:self.countingLabel]; 141 | } 142 | 143 | 144 | // Add circle params 145 | 146 | _circle.lineWidth = [_lineWidth floatValue]; 147 | _circleBackground.lineWidth = [_lineWidth floatValue]; 148 | _circleBackground.strokeEnd = 1.0; 149 | _circle.strokeColor = _strokeColor.CGColor; 150 | 151 | // Add Animation 152 | CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 153 | pathAnimation.duration = self.duration; 154 | pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 155 | pathAnimation.fromValue = @0.0f; 156 | pathAnimation.toValue = @([_current floatValue] / [_total floatValue]); 157 | [_circle addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 158 | _circle.strokeEnd = [_current floatValue] / [_total floatValue]; 159 | 160 | [_countingLabel countFrom:0 to:[_current floatValue]/([_total floatValue]/100.0) withDuration:self.duration]; 161 | 162 | 163 | // Check if user wants to add a gradient from the start color to the bar color 164 | if (_strokeColorGradientStart) { 165 | 166 | // Add gradient 167 | self.gradientMask = [CAShapeLayer layer]; 168 | self.gradientMask.fillColor = [[UIColor clearColor] CGColor]; 169 | self.gradientMask.strokeColor = [[UIColor blackColor] CGColor]; 170 | self.gradientMask.lineWidth = _circle.lineWidth; 171 | self.gradientMask.lineCap = kCALineCapRound; 172 | CGRect gradientFrame = CGRectMake(0, 0, 2*self.bounds.size.width, 2*self.bounds.size.height); 173 | self.gradientMask.frame = gradientFrame; 174 | self.gradientMask.path = _circle.path; 175 | 176 | CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 177 | gradientLayer.startPoint = CGPointMake(0.5,1.0); 178 | gradientLayer.endPoint = CGPointMake(0.5,0.0); 179 | gradientLayer.frame = gradientFrame; 180 | UIColor *endColor = (_strokeColor ? _strokeColor : [UIColor greenColor]); 181 | NSArray *colors = @[ 182 | (id)endColor.CGColor, 183 | (id)_strokeColorGradientStart.CGColor 184 | ]; 185 | gradientLayer.colors = colors; 186 | 187 | [gradientLayer setMask:self.gradientMask]; 188 | 189 | [_circle addSublayer:gradientLayer]; 190 | 191 | self.gradientMask.strokeEnd = [_current floatValue] / [_total floatValue]; 192 | 193 | [self.gradientMask addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 194 | } 195 | } 196 | 197 | 198 | 199 | - (void)growChartByAmount:(NSNumber *)growAmount 200 | { 201 | NSNumber *updatedValue = [NSNumber numberWithFloat:[_current floatValue] + [growAmount floatValue]]; 202 | 203 | // Add animation 204 | [self updateChartByCurrent:updatedValue]; 205 | } 206 | 207 | 208 | -(void)updateChartByCurrent:(NSNumber *)current{ 209 | 210 | [self updateChartByCurrent:current 211 | byTotal:_total]; 212 | 213 | } 214 | 215 | -(void)updateChartByCurrent:(NSNumber *)current byTotal:(NSNumber *)total { 216 | // Add animation 217 | CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 218 | pathAnimation.duration = self.duration; 219 | pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 220 | pathAnimation.fromValue = @([_current floatValue] / [_total floatValue]); 221 | pathAnimation.toValue = @([current floatValue] / [total floatValue]); 222 | _circle.strokeEnd = [current floatValue] / [total floatValue]; 223 | 224 | if (_strokeColorGradientStart) { 225 | self.gradientMask.strokeEnd = _circle.strokeEnd; 226 | [self.gradientMask addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 227 | } 228 | [_circle addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 229 | 230 | if (_displayCountingLabel) { 231 | [self.countingLabel countFrom:fmin([_current floatValue], [_total floatValue]) to:fmin([current floatValue], [total floatValue]) withDuration:self.duration]; 232 | } 233 | 234 | _current = current; 235 | _total = total; 236 | } 237 | 238 | @end 239 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCColor.h: -------------------------------------------------------------------------------- 1 | // 2 | // UUColor.h 3 | // UUChart 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | /* 11 | * System Versioning Preprocessor Macros 12 | */ 13 | 14 | #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width) 15 | 16 | #define SCGrey [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0f] 17 | #define SCLightBlue [UIColor colorWithRed:94.0/255.0 green:147.0/255.0 blue:196.0/255.0 alpha:1.0f] 18 | #define SCGreen [UIColor colorWithRed:77.0/255.0 green:186.0/255.0 blue:122.0/255.0 alpha:1.0f] 19 | #define SCTitleColor [UIColor colorWithRed:0.0/255.0 green:189.0/255.0 blue:113.0/255.0 alpha:1.0f] 20 | #define SCButtonGrey [UIColor colorWithRed:141.0/255.0 green:141.0/255.0 blue:141.0/255.0 alpha:1.0f] 21 | #define SCFreshGreen [UIColor colorWithRed:77.0/255.0 green:196.0/255.0 blue:122.0/255.0 alpha:1.0f] 22 | #define SCRed [UIColor colorWithRed:245.0/255.0 green:94.0/255.0 blue:78.0/255.0 alpha:1.0f] 23 | #define SCMauve [UIColor colorWithRed:88.0/255.0 green:75.0/255.0 blue:103.0/255.0 alpha:1.0f] 24 | #define SCBrown [UIColor colorWithRed:119.0/255.0 green:107.0/255.0 blue:95.0/255.0 alpha:1.0f] 25 | #define SCBlue [UIColor colorWithRed:82.0/255.0 green:116.0/255.0 blue:188.0/255.0 alpha:1.0f] 26 | #define SCDarkBlue [UIColor colorWithRed:121.0/255.0 green:134.0/255.0 blue:142.0/255.0 alpha:1.0f] 27 | #define SCYellow [UIColor colorWithRed:242.0/255.0 green:197.0/255.0 blue:117.0/255.0 alpha:1.0f] 28 | #define SCWhite [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0f] 29 | #define SCDeepGrey [UIColor colorWithRed:99.0/255.0 green:99.0/255.0 blue:99.0/255.0 alpha:1.0f] 30 | #define SCPinkGrey [UIColor colorWithRed:200.0/255.0 green:193.0/255.0 blue:193.0/255.0 alpha:1.0f] 31 | #define SCHealYellow [UIColor colorWithRed:245.0/255.0 green:242.0/255.0 blue:238.0/255.0 alpha:1.0f] 32 | #define SCLightGrey [UIColor colorWithRed:225.0/255.0 green:225.0/255.0 blue:225.0/255.0 alpha:1.0f] 33 | #define SCCleanGrey [UIColor colorWithRed:251.0/255.0 green:251.0/255.0 blue:251.0/255.0 alpha:1.0f] 34 | #define SCLightYellow [UIColor colorWithRed:241.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0f] 35 | #define SCDarkYellow [UIColor colorWithRed:152.0/255.0 green:150.0/255.0 blue:159.0/255.0 alpha:1.0f] 36 | #define SCPinkDark [UIColor colorWithRed:170.0/255.0 green:165.0/255.0 blue:165.0/255.0 alpha:1.0f] 37 | #define SCCloudWhite [UIColor colorWithRed:244.0/255.0 green:244.0/255.0 blue:244.0/255.0 alpha:1.0f] 38 | #define SCBlack [UIColor colorWithRed:45.0/255.0 green:45.0/255.0 blue:45.0/255.0 alpha:1.0f] 39 | #define SCStarYellow [UIColor colorWithRed:252.0/255.0 green:223.0/255.0 blue:101.0/255.0 alpha:1.0f] 40 | #define SCTwitterColor [UIColor colorWithRed:0.0/255.0 green:171.0/255.0 blue:243.0/255.0 alpha:1.0] 41 | #define SCWeiboColor [UIColor colorWithRed:250.0/255.0 green:0.0/255.0 blue:33.0/255.0 alpha:1.0] 42 | #define SCiOSGreenColor [UIColor colorWithRed:98.0/255.0 green:247.0/255.0 blue:77.0/255.0 alpha:1.0] 43 | #define SCRandomColor [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1.0f] 44 | 45 | //范围 46 | struct Range { 47 | CGFloat max; 48 | CGFloat min; 49 | }; 50 | typedef struct Range CGRange; 51 | CG_INLINE CGRange CGRangeMake(CGFloat max, CGFloat min); 52 | 53 | CG_INLINE CGRange 54 | CGRangeMake(CGFloat max, CGFloat min){ 55 | CGRange p; 56 | p.max = max; 57 | p.min = min; 58 | return p; 59 | } 60 | 61 | static const CGRange CGRangeZero = {0,0}; 62 | 63 | @interface SCColor : NSObject 64 | - (UIImage *)imageFromColor:(UIColor *)color; 65 | @end 66 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCColor.m: -------------------------------------------------------------------------------- 1 | // 2 | // UUColor.m 3 | // UUChart 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCColor.h" 10 | 11 | @implementation SCColor 12 | 13 | -(id)init{ 14 | if (self = [super init]) { 15 | 16 | } 17 | return self; 18 | } 19 | 20 | -(UIImage *)imageFromColor:(UIColor*)color 21 | { 22 | CGRect rect = CGRectMake(0, 0, 1, 1); 23 | UIGraphicsBeginImageContext(rect.size); 24 | CGContextRef context = UIGraphicsGetCurrentContext(); 25 | CGContextSetFillColorWithColor(context,[color CGColor]); 26 | CGContextFillRect(context, rect); 27 | UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 28 | UIGraphicsEndImageContext(); 29 | return img; 30 | } 31 | 32 | 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCGenericChart.h: -------------------------------------------------------------------------------- 1 | // 2 | // PNGenericChart.h 3 | // PNChartDemo 4 | // 5 | // Created by Andi Palo on 26/02/15. 6 | // Copyright (c) 2015 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, PNLegendPosition) { 12 | PNLegendPositionTop = 0, 13 | PNLegendPositionBottom = 1, 14 | PNLegendPositionLeft = 2, 15 | PNLegendPositionRight = 3 16 | }; 17 | 18 | typedef NS_ENUM(NSUInteger, PNLegendItemStyle) { 19 | PNLegendItemStyleStacked = 0, 20 | PNLegendItemStyleSerial = 1 21 | }; 22 | 23 | @interface SCGenericChart : UIView 24 | 25 | @property (assign, nonatomic) BOOL hasLegend; 26 | @property (assign, nonatomic) PNLegendPosition legendPosition; 27 | @property (assign, nonatomic) PNLegendItemStyle legendStyle; 28 | 29 | @property (assign, nonatomic) UIFont *legendFont; 30 | @property (assign, nonatomic) UIColor *legendFontColor; 31 | @property (assign, nonatomic) NSUInteger labelRowsInSerialMode; 32 | 33 | /** 34 | * returns the Legend View, or nil if no chart data is present. 35 | * The origin of the legend frame is 0,0 but you can set it with setFrame:(CGRect) 36 | * 37 | * @param mWidth Maximum width of legend. Height will depend on this and font size 38 | * 39 | * @return UIView of Legend 40 | */ 41 | - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth; 42 | 43 | 44 | - (void) setupDefaultValues; 45 | @end 46 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCGenericChart.m: -------------------------------------------------------------------------------- 1 | // 2 | // PNGenericChart.m 3 | // PNChartDemo 4 | // 5 | // Created by Andi Palo on 26/02/15. 6 | // Copyright (c) 2015 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import "SCGenericChart.h" 10 | 11 | @interface SCGenericChart () 12 | 13 | 14 | 15 | @end 16 | 17 | @implementation SCGenericChart 18 | 19 | /* 20 | // Only override drawRect: if you perform custom drawing. 21 | // An empty implementation adversely affects performance during animation. 22 | - (void)drawRect:(CGRect)rect { 23 | // Drawing code 24 | } 25 | */ 26 | 27 | - (void) setupDefaultValues{ 28 | self.hasLegend = YES; 29 | self.legendPosition = PNLegendPositionBottom; 30 | self.legendStyle = PNLegendItemStyleStacked; 31 | self.labelRowsInSerialMode = 1; 32 | } 33 | 34 | 35 | 36 | /** 37 | * to be implemented in subclass 38 | */ 39 | - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{ 40 | [self doesNotRecognizeSelector:_cmd]; 41 | return nil; 42 | } 43 | 44 | - (void) setLabelRowsInSerialMode:(NSUInteger)num{ 45 | if (self.legendStyle == PNLegendItemStyleSerial) { 46 | _labelRowsInSerialMode = num; 47 | }else{ 48 | _labelRowsInSerialMode = 1; 49 | } 50 | } 51 | 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCLineChart.h: -------------------------------------------------------------------------------- 1 | // 2 | // UULineChart.h 3 | // UUChartDemo 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import "SCColor.h" 12 | 13 | #define chartMargin 10 14 | #define xLabelMargin 15 15 | #define yLabelMargin 15 16 | #define UULabelHeight 10 17 | #define UUYLabelwidth 30 18 | #define UUTagLabelwidth 80 19 | 20 | @interface SCLineChart : UIView 21 | 22 | @property (strong, nonatomic) NSArray * xLabels; 23 | 24 | @property (strong, nonatomic) NSArray * yLabels; 25 | 26 | @property (strong, nonatomic) NSArray * yValues; 27 | 28 | @property (nonatomic, strong) NSArray * colors; 29 | 30 | @property (nonatomic) CGFloat xLabelWidth; 31 | @property (nonatomic) CGFloat yValueMin; 32 | @property (nonatomic) CGFloat yValueMax; 33 | 34 | @property (nonatomic, assign) CGRange markRange; 35 | 36 | @property (nonatomic, assign) CGRange chooseRange; 37 | 38 | @property (nonatomic, assign) BOOL showRange; 39 | 40 | @property (nonatomic, retain) NSMutableArray *ShowHorizonLine; 41 | @property (nonatomic, retain) NSMutableArray *ShowMaxMinArray; 42 | 43 | -(void)strokeChart; 44 | 45 | + (CGSize)sizeOfString:(NSString *)text withWidth:(float)width font:(UIFont *)font; 46 | @end 47 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCLineChart.m: -------------------------------------------------------------------------------- 1 | // 2 | // UULineChart.m 3 | // UUChartDemo 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCLineChart.h" 10 | #import "SCColor.h" 11 | #import "SCChartLabel.h" 12 | #import "SCTool.h" 13 | 14 | @implementation SCLineChart 15 | 16 | - (id)initWithFrame:(CGRect)frame 17 | { 18 | self = [super initWithFrame:frame]; 19 | if (self) { 20 | // Initialization code 21 | self.clipsToBounds = YES; 22 | } 23 | return self; 24 | } 25 | 26 | -(void)setYValues:(NSArray *)yValues 27 | { 28 | _yValues = yValues; 29 | [self setYLabels:yValues]; 30 | } 31 | 32 | -(void)setYLabels:(NSArray *)yLabels 33 | { 34 | CGFloat max = 0; 35 | CGFloat min = 1000000000; 36 | NSInteger rowCount = 0; // 自动计算每个图表适合的行数 37 | for (NSArray * ary in yLabels) { 38 | for (NSString *valueString in ary) { 39 | CGFloat value = [valueString floatValue]; 40 | if (value > max) { 41 | max = value; 42 | } 43 | if (value < min) { 44 | min = value; 45 | } 46 | } 47 | } 48 | if (self.showRange) { 49 | _yValueMin = min; 50 | }else{ 51 | _yValueMin = 0; 52 | } 53 | _yValueMax = max; 54 | 55 | if (_chooseRange.max!=_chooseRange.min) { // 自定义数值范围 56 | _yValueMax = _chooseRange.max; 57 | _yValueMin = _chooseRange.min; 58 | } else { // 自动计算数值范围和合适的行数 59 | rowCount = [SCTool rowCountWithValueMax:_yValueMax] == 0 ? 5 : [SCTool rowCountWithValueMax:_yValueMax]; 60 | _yValueMax = [SCTool rangeMaxWithValueMax:_yValueMax] == 0 ? 100 : [SCTool rangeMaxWithValueMax:_yValueMax]; 61 | _yValueMin = 0; 62 | } 63 | 64 | float level = (_yValueMax-_yValueMin) /rowCount; // 每个区间的差值 65 | CGFloat chartCavanHeight = self.frame.size.height - UULabelHeight*3; 66 | CGFloat levelHeight = chartCavanHeight /rowCount; // 每个区间的高度 67 | for (int i=0; i0) { 81 | 82 | CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 83 | UIBezierPath *path = [UIBezierPath bezierPath]; 84 | [path moveToPoint:CGPointMake(UUYLabelwidth,UULabelHeight+i*levelHeight)]; 85 | [path addLineToPoint:CGPointMake(self.frame.size.width,UULabelHeight+i*levelHeight)]; 86 | [path closePath]; 87 | shapeLayer.path = path.CGPath; 88 | shapeLayer.strokeColor = [[[UIColor blackColor] colorWithAlphaComponent:0.1] CGColor]; 89 | shapeLayer.fillColor = [[UIColor whiteColor] CGColor]; 90 | shapeLayer.lineWidth = 1; 91 | [self.layer addSublayer:shapeLayer]; 92 | } 93 | } 94 | } 95 | 96 | 97 | -(void)setXLabels:(NSArray *)xLabels 98 | { 99 | _xLabels = xLabels; 100 | CGFloat num = 0; 101 | if (xLabels.count>=20) { 102 | num=20.0; 103 | }else if (xLabels.count<=1){ 104 | num=1.0; 105 | }else{ 106 | num = xLabels.count; 107 | } 108 | _xLabelWidth = (self.frame.size.width - UUYLabelwidth)/num; 109 | 110 | for (int i=0; i=num){ 170 | min = num; 171 | min_i = j; 172 | } 173 | } 174 | 175 | //划线 176 | CAShapeLayer *_chartLine = [CAShapeLayer layer]; 177 | _chartLine.lineCap = kCALineCapRound; 178 | _chartLine.lineJoin = kCALineJoinBevel; 179 | _chartLine.fillColor = [[UIColor whiteColor] CGColor]; 180 | _chartLine.lineWidth = 2.0; 181 | _chartLine.strokeEnd = 0.0; 182 | [self.layer addSublayer:_chartLine]; 183 | 184 | UIBezierPath *progressline = [UIBezierPath bezierPath]; 185 | CGFloat firstValue = [[childAry objectAtIndex:0] floatValue]; 186 | CGFloat xPosition = (UUYLabelwidth + _xLabelWidth/2.0); 187 | CGFloat chartCavanHeight = self.frame.size.height - UULabelHeight*3; 188 | 189 | float grade = ((float)firstValue-_yValueMin) / ((float)_yValueMax-_yValueMin); 190 | 191 | //第一个点 192 | BOOL isShowMaxAndMinPoint = YES; 193 | if (self.ShowMaxMinArray) { 194 | if ([self.ShowMaxMinArray[i] intValue]>0) { 195 | isShowMaxAndMinPoint = (max_i==0 || min_i==0)?NO:YES; 196 | }else{ 197 | isShowMaxAndMinPoint = YES; 198 | } 199 | } 200 | [self addPoint:CGPointMake(xPosition, chartCavanHeight - grade * chartCavanHeight+UULabelHeight) 201 | index:i 202 | isShow:isShowMaxAndMinPoint 203 | value:firstValue]; 204 | 205 | 206 | [progressline moveToPoint:CGPointMake(xPosition, chartCavanHeight - grade * chartCavanHeight+UULabelHeight)]; 207 | [progressline setLineWidth:2.0]; 208 | [progressline setLineCapStyle:kCGLineCapRound]; 209 | [progressline setLineJoinStyle:kCGLineJoinRound]; 210 | NSInteger index = 0; 211 | for (NSString * valueString in childAry) { 212 | 213 | float grade =([valueString floatValue]-_yValueMin) / ((float)_yValueMax-_yValueMin); 214 | if (index != 0) { 215 | 216 | CGPoint point = CGPointMake(xPosition+index*_xLabelWidth, chartCavanHeight - grade * chartCavanHeight+UULabelHeight); 217 | [progressline addLineToPoint:point]; 218 | 219 | BOOL isShowMaxAndMinPoint = YES; 220 | if (self.ShowMaxMinArray) { 221 | if ([self.ShowMaxMinArray[i] intValue]>0) { 222 | isShowMaxAndMinPoint = (max_i==index || min_i==index)?NO:YES; 223 | }else{ 224 | isShowMaxAndMinPoint = YES; 225 | } 226 | } 227 | [progressline moveToPoint:point]; 228 | [self addPoint:point 229 | index:i 230 | isShow:isShowMaxAndMinPoint 231 | value:[valueString floatValue]]; 232 | 233 | // [progressline stroke]; 234 | } 235 | index += 1; 236 | } 237 | 238 | _chartLine.path = progressline.CGPath; 239 | if ([[_colors objectAtIndex:i] CGColor]) { 240 | _chartLine.strokeColor = [[_colors objectAtIndex:i] CGColor]; 241 | }else{ 242 | _chartLine.strokeColor = [SCGreen CGColor]; 243 | } 244 | CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 245 | pathAnimation.duration = childAry.count*0.4; 246 | pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 247 | pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; 248 | pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; 249 | pathAnimation.autoreverses = NO; 250 | [_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 251 | 252 | _chartLine.strokeEnd = 1.0; 253 | } 254 | } 255 | 256 | - (void)addPoint:(CGPoint)point index:(NSInteger)index isShow:(BOOL)isHollow value:(CGFloat)value 257 | { 258 | UIView *view = [[UIView alloc]initWithFrame:CGRectMake(5, 5, 8, 8)]; 259 | view.center = point; 260 | view.layer.masksToBounds = YES; 261 | view.layer.cornerRadius = 4; 262 | view.layer.borderWidth = 2; 263 | view.layer.borderColor = [[_colors objectAtIndex:index] CGColor]?[[_colors objectAtIndex:index] CGColor]:SCGreen.CGColor; 264 | 265 | if (isHollow) { 266 | view.backgroundColor = [UIColor whiteColor]; 267 | }else{ 268 | view.backgroundColor = [_colors objectAtIndex:index]?[_colors objectAtIndex:index]:SCGreen; 269 | UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(point.x-UUTagLabelwidth/2.0, point.y-UULabelHeight*2, UUTagLabelwidth, UULabelHeight)]; 270 | label.font = [UIFont systemFontOfSize:10]; 271 | label.textAlignment = NSTextAlignmentCenter; 272 | label.textColor = view.backgroundColor; 273 | label.text = [NSString stringWithFormat:@"%d",(int)value]; 274 | [self addSubview:label]; 275 | } 276 | 277 | [self addSubview:view]; 278 | } 279 | 280 | + (CGSize)sizeOfString:(NSString *)text withWidth:(float)width font:(UIFont *)font 281 | { 282 | NSInteger ch; 283 | CGSize size = CGSizeMake(width, MAXFLOAT); 284 | 285 | if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { 286 | NSDictionary *tdic = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; 287 | size = [text boundingRectWithSize:size 288 | options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading 289 | attributes:tdic 290 | context:nil].size; 291 | } else { 292 | #pragma clang diagnostic push 293 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 294 | size = [text sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByCharWrapping]; 295 | #pragma clang diagnostic pop 296 | } 297 | ch = size.height; 298 | 299 | return size; 300 | } 301 | 302 | 303 | @end 304 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCPieChart.h: -------------------------------------------------------------------------------- 1 | // 2 | // PNPieChart.h 3 | // PNChartDemo 4 | // 5 | // Created by Hang Zhang on 14-5-5. 6 | // Copyright (c) 2014年 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SCPieChartDataItem.h" 11 | #import "SCGenericChart.h" 12 | #import "SCChartDelegate.h" 13 | 14 | @interface SCPieChart : SCGenericChart 15 | 16 | - (id)initWithFrame:(CGRect)frame items:(NSArray *)items; 17 | 18 | @property (nonatomic, readonly) NSArray *items; 19 | 20 | /** Default is 18-point Avenir Medium. */ 21 | @property (nonatomic) UIFont *descriptionTextFont; 22 | 23 | /** Default is white. */ 24 | @property (nonatomic) UIColor *descriptionTextColor; 25 | 26 | /** Default is black, with an alpha of 0.4. */ 27 | @property (nonatomic) UIColor *descriptionTextShadowColor; 28 | 29 | /** Default is CGSizeMake(0, 1). */ 30 | @property (nonatomic) CGSize descriptionTextShadowOffset; 31 | 32 | /** Default is 1.0. */ 33 | @property (nonatomic) NSTimeInterval duration; 34 | 35 | /** Show only values, this is useful when legend is present */ 36 | @property (nonatomic) BOOL showOnlyValues; 37 | 38 | /** Show absolute values not relative i.e. percentages */ 39 | @property (nonatomic) BOOL showAbsoluteValues; 40 | 41 | @property (nonatomic, weak) id delegate; 42 | 43 | - (void)updateChartByNumbers:(NSArray *)numbers; 44 | 45 | - (void)strokeChart; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCPieChart.m: -------------------------------------------------------------------------------- 1 | // 2 | // PNPieChart.m 3 | // PNChartDemo 4 | // 5 | // Created by Hang Zhang on 14-5-5. 6 | // Copyright (c) 2014年 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import "SCPieChart.h" 10 | //needed for the expected label size 11 | #import "SCLineChart.h" 12 | 13 | @interface SCPieChart() 14 | 15 | @property (nonatomic) NSArray *items; 16 | @property (nonatomic) NSArray *endPercentages; 17 | 18 | @property (nonatomic) CGFloat outerCircleRadius; 19 | @property (nonatomic) CGFloat innerCircleRadius; 20 | 21 | @property (nonatomic) UIView *contentView; 22 | @property (nonatomic) CAShapeLayer *pieLayer; 23 | @property (nonatomic) NSMutableArray *descriptionLabels; 24 | @property (strong, nonatomic) CAShapeLayer *sectorHighlight; 25 | 26 | - (void)loadDefault; 27 | 28 | - (UILabel *)descriptionLabelForItemAtIndex:(NSUInteger)index; 29 | - (SCPieChartDataItem *)dataItemForIndex:(NSUInteger)index; 30 | - (CGFloat)startPercentageForItemAtIndex:(NSUInteger)index; 31 | - (CGFloat)endPercentageForItemAtIndex:(NSUInteger)index; 32 | - (CGFloat)ratioForItemAtIndex:(NSUInteger)index; 33 | 34 | - (CAShapeLayer *)newCircleLayerWithRadius:(CGFloat)radius 35 | borderWidth:(CGFloat)borderWidth 36 | fillColor:(UIColor *)fillColor 37 | borderColor:(UIColor *)borderColor 38 | startPercentage:(CGFloat)startPercentage 39 | endPercentage:(CGFloat)endPercentage; 40 | 41 | 42 | @end 43 | 44 | 45 | @implementation SCPieChart 46 | 47 | -(id)initWithFrame:(CGRect)frame items:(NSArray *)items{ 48 | self = [self initWithFrame:frame]; 49 | if(self){ 50 | _items = [NSArray arrayWithArray:items]; 51 | _outerCircleRadius = CGRectGetWidth(self.bounds) / 2; 52 | _innerCircleRadius = CGRectGetWidth(self.bounds) / 6; 53 | 54 | _descriptionTextColor = [UIColor whiteColor]; 55 | _descriptionTextFont = [UIFont fontWithName:@"Avenir-Medium" size:18.0]; 56 | _descriptionTextShadowColor = [[UIColor blackColor] colorWithAlphaComponent:0.4]; 57 | _descriptionTextShadowOffset = CGSizeMake(0, 1); 58 | _duration = 1.0; 59 | 60 | [super setupDefaultValues]; 61 | [self loadDefault]; 62 | } 63 | 64 | return self; 65 | } 66 | 67 | - (void)loadDefault{ 68 | __block CGFloat currentTotal = 0; 69 | CGFloat total = [[self.items valueForKeyPath:@"@sum.value"] floatValue]; 70 | NSMutableArray *endPercentages = [NSMutableArray new]; 71 | [_items enumerateObjectsUsingBlock:^(SCPieChartDataItem *item, NSUInteger idx, BOOL *stop) { 72 | if (total == 0){ 73 | [endPercentages addObject:@(1.0 / _items.count * (idx + 1))]; 74 | }else{ 75 | currentTotal += item.value; 76 | [endPercentages addObject:@(currentTotal / total)]; 77 | } 78 | }]; 79 | self.endPercentages = [endPercentages copy]; 80 | 81 | [_contentView removeFromSuperview]; 82 | _contentView = [[UIView alloc] initWithFrame:self.bounds]; 83 | [self addSubview:_contentView]; 84 | _descriptionLabels = [NSMutableArray new]; 85 | 86 | _pieLayer = [CAShapeLayer layer]; 87 | [_contentView.layer addSublayer:_pieLayer]; 88 | } 89 | 90 | #pragma mark - 91 | 92 | - (void)strokeChart{ 93 | [self loadDefault]; 94 | 95 | SCPieChartDataItem *currentItem; 96 | for (int i = 0; i < _items.count; i++) { 97 | currentItem = [self dataItemForIndex:i]; 98 | 99 | 100 | CGFloat startPercnetage = [self startPercentageForItemAtIndex:i]; 101 | CGFloat endPercentage = [self endPercentageForItemAtIndex:i]; 102 | 103 | CGFloat radius = _innerCircleRadius + (_outerCircleRadius - _innerCircleRadius) / 2; 104 | CGFloat borderWidth = _outerCircleRadius - _innerCircleRadius; 105 | 106 | CAShapeLayer *currentPieLayer = [self newCircleLayerWithRadius:radius 107 | borderWidth:borderWidth 108 | fillColor:[UIColor clearColor] 109 | borderColor:currentItem.color 110 | startPercentage:startPercnetage 111 | endPercentage:endPercentage]; 112 | [_pieLayer addSublayer:currentPieLayer]; 113 | } 114 | 115 | [self maskChart]; 116 | 117 | for (int i = 0; i < _items.count; i++) { 118 | UILabel *descriptionLabel = [self descriptionLabelForItemAtIndex:i]; 119 | [_contentView addSubview:descriptionLabel]; 120 | [_descriptionLabels addObject:descriptionLabel]; 121 | } 122 | } 123 | 124 | - (UILabel *)descriptionLabelForItemAtIndex:(NSUInteger)index{ 125 | SCPieChartDataItem *currentDataItem = [self dataItemForIndex:index]; 126 | CGFloat distance = _innerCircleRadius + (_outerCircleRadius - _innerCircleRadius) / 2; 127 | CGFloat centerPercentage = ([self startPercentageForItemAtIndex:index] + [self endPercentageForItemAtIndex:index])/ 2; 128 | CGFloat rad = centerPercentage * 2 * M_PI; 129 | 130 | UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 80)]; 131 | NSString *titleText = currentDataItem.textDescription; 132 | NSString *titleValue; 133 | 134 | if (self.showAbsoluteValues) { 135 | titleValue = [NSString stringWithFormat:@"%.0f",currentDataItem.value]; 136 | }else{ 137 | titleValue = [NSString stringWithFormat:@"%.0f%%",[self ratioForItemAtIndex:index] * 100]; 138 | } 139 | if(!titleText || self.showOnlyValues){ 140 | descriptionLabel.text = titleValue; 141 | } 142 | else { 143 | NSString* str = [titleValue stringByAppendingString:[NSString stringWithFormat:@"\n%@",titleText]]; 144 | descriptionLabel.text = str ; 145 | } 146 | 147 | CGPoint center = CGPointMake(_outerCircleRadius + distance * sin(rad), 148 | _outerCircleRadius - distance * cos(rad)); 149 | 150 | descriptionLabel.font = _descriptionTextFont; 151 | CGSize labelSize = [descriptionLabel.text sizeWithAttributes:@{NSFontAttributeName:descriptionLabel.font}]; 152 | descriptionLabel.frame = CGRectMake(descriptionLabel.frame.origin.x, descriptionLabel.frame.origin.y, 153 | descriptionLabel.frame.size.width, labelSize.height); 154 | descriptionLabel.numberOfLines = 0; 155 | descriptionLabel.textColor = _descriptionTextColor; 156 | descriptionLabel.shadowColor = _descriptionTextShadowColor; 157 | descriptionLabel.shadowOffset = _descriptionTextShadowOffset; 158 | descriptionLabel.textAlignment = NSTextAlignmentCenter; 159 | descriptionLabel.center = center; 160 | descriptionLabel.alpha = 0; 161 | descriptionLabel.backgroundColor = [UIColor clearColor]; 162 | return descriptionLabel; 163 | } 164 | 165 | - (SCPieChartDataItem *)dataItemForIndex:(NSUInteger)index{ 166 | return self.items[index]; 167 | } 168 | 169 | - (CGFloat)startPercentageForItemAtIndex:(NSUInteger)index{ 170 | if(index == 0){ 171 | return 0; 172 | } 173 | 174 | return [_endPercentages[index - 1] floatValue]; 175 | } 176 | 177 | - (CGFloat)endPercentageForItemAtIndex:(NSUInteger)index{ 178 | return [_endPercentages[index] floatValue]; 179 | } 180 | 181 | - (CGFloat)ratioForItemAtIndex:(NSUInteger)index{ 182 | return [self endPercentageForItemAtIndex:index] - [self startPercentageForItemAtIndex:index]; 183 | } 184 | 185 | #pragma mark private methods 186 | 187 | - (CAShapeLayer *)newCircleLayerWithRadius:(CGFloat)radius 188 | borderWidth:(CGFloat)borderWidth 189 | fillColor:(UIColor *)fillColor 190 | borderColor:(UIColor *)borderColor 191 | startPercentage:(CGFloat)startPercentage 192 | endPercentage:(CGFloat)endPercentage{ 193 | CAShapeLayer *circle = [CAShapeLayer layer]; 194 | 195 | CGPoint center = CGPointMake(CGRectGetMidX(self.bounds),CGRectGetMidY(self.bounds)); 196 | 197 | UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center 198 | radius:radius 199 | startAngle:-M_PI_2 200 | endAngle:M_PI_2 * 3 201 | clockwise:YES]; 202 | 203 | circle.fillColor = fillColor.CGColor; 204 | circle.strokeColor = borderColor.CGColor; 205 | circle.strokeStart = startPercentage; 206 | circle.strokeEnd = endPercentage; 207 | circle.lineWidth = borderWidth; 208 | circle.path = path.CGPath; 209 | 210 | return circle; 211 | } 212 | 213 | - (void)maskChart{ 214 | CGFloat radius = _innerCircleRadius + (_outerCircleRadius - _innerCircleRadius) / 2; 215 | CGFloat borderWidth = _outerCircleRadius - _innerCircleRadius; 216 | CAShapeLayer *maskLayer = [self newCircleLayerWithRadius:radius 217 | borderWidth:borderWidth 218 | fillColor:[UIColor clearColor] 219 | borderColor:[UIColor blackColor] 220 | startPercentage:0 221 | endPercentage:1]; 222 | 223 | _pieLayer.mask = maskLayer; 224 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 225 | animation.duration = _duration; 226 | animation.fromValue = @0; 227 | animation.toValue = @1; 228 | animation.delegate = self; 229 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 230 | animation.removedOnCompletion = YES; 231 | [maskLayer addAnimation:animation forKey:@"circleAnimation"]; 232 | } 233 | 234 | - (void)createArcAnimationForLayer:(CAShapeLayer *)layer 235 | forKey:(NSString *)key 236 | fromValue:(NSNumber *)from 237 | toValue:(NSNumber *)to 238 | delegate:(id)delegate{ 239 | CABasicAnimation *arcAnimation = [CABasicAnimation animationWithKeyPath:key]; 240 | arcAnimation.fromValue = @0; 241 | arcAnimation.toValue = to; 242 | arcAnimation.delegate = delegate; 243 | arcAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; 244 | [layer addAnimation:arcAnimation forKey:key]; 245 | [layer setValue:to forKey:key]; 246 | } 247 | 248 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ 249 | [_descriptionLabels enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 250 | [UIView animateWithDuration:0.2 animations:^(){ 251 | [obj setAlpha:1]; 252 | }]; 253 | }]; 254 | } 255 | 256 | - (void)didTouchAt:(CGPoint)touchLocation 257 | { 258 | CGPoint circleCenter = CGPointMake(_contentView.bounds.size.width/2, _contentView.bounds.size.height/2); 259 | 260 | CGFloat distanceFromCenter = sqrtf(powf((touchLocation.y - circleCenter.y),2) + powf((touchLocation.x - circleCenter.x),2)); 261 | 262 | if (distanceFromCenter < _innerCircleRadius) { 263 | if ([self.delegate respondsToSelector:@selector(didUnselectPieItem)]) { 264 | [self.delegate didUnselectPieItem]; 265 | } 266 | [self.sectorHighlight removeFromSuperlayer]; 267 | return; 268 | } 269 | 270 | CGFloat percentage = [self findPercentageOfAngleInCircle:circleCenter fromPoint:touchLocation]; 271 | int index = 0; 272 | while (percentage > [self endPercentageForItemAtIndex:index]) { 273 | index ++; 274 | } 275 | 276 | if ([self.delegate respondsToSelector:@selector(userClickedOnPieIndexItem:)]) { 277 | [self.delegate userClickedOnPieIndexItem:index]; 278 | } 279 | 280 | if (self.sectorHighlight) { 281 | [self.sectorHighlight removeFromSuperlayer]; 282 | } 283 | SCPieChartDataItem *currentItem = [self dataItemForIndex:index]; 284 | 285 | CGFloat red,green,blue,alpha; 286 | UIColor *old = currentItem.color; 287 | [old getRed:&red green:&green blue:&blue alpha:&alpha]; 288 | alpha /= 2; 289 | UIColor *newColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 290 | 291 | CGFloat startPercnetage = [self startPercentageForItemAtIndex:index]; 292 | CGFloat endPercentage = [self endPercentageForItemAtIndex:index]; 293 | self.sectorHighlight = [self newCircleLayerWithRadius:_outerCircleRadius + 5 294 | borderWidth:10 295 | fillColor:[UIColor clearColor] 296 | borderColor:newColor 297 | startPercentage:startPercnetage 298 | endPercentage:endPercentage]; 299 | [_contentView.layer addSublayer:self.sectorHighlight]; 300 | } 301 | 302 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 303 | { 304 | for (UITouch *touch in touches) { 305 | CGPoint touchLocation = [touch locationInView:_contentView]; 306 | [self didTouchAt:touchLocation]; 307 | } 308 | } 309 | 310 | - (CGFloat) findPercentageOfAngleInCircle:(CGPoint)center fromPoint:(CGPoint)reference{ 311 | //Find angle of line Passing In Reference And Center 312 | CGFloat angleOfLine = atanf((reference.y - center.y) / (reference.x - center.x)); 313 | CGFloat percentage = (angleOfLine + M_PI/2)/(2 * M_PI); 314 | return (reference.x - center.x) > 0 ? percentage : percentage + .5; 315 | } 316 | 317 | - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{ 318 | if ([self.items count] < 1) { 319 | return nil; 320 | } 321 | 322 | /* This is a small circle that refers to the chart data */ 323 | CGFloat legendCircle = 16; 324 | 325 | CGFloat hSpacing = 0; 326 | 327 | CGFloat beforeLabel = legendCircle + hSpacing; 328 | 329 | /* x and y are the coordinates of the starting point of each legend item */ 330 | CGFloat x = 0; 331 | CGFloat y = 0; 332 | 333 | /* accumulated width and height */ 334 | CGFloat totalWidth = 0; 335 | CGFloat totalHeight = 0; 336 | 337 | NSMutableArray *legendViews = [[NSMutableArray alloc] init]; 338 | 339 | /* Determine the max width of each legend item */ 340 | CGFloat maxLabelWidth; 341 | if (self.legendStyle == PNLegendItemStyleStacked) { 342 | maxLabelWidth = mWidth - beforeLabel; 343 | }else{ 344 | maxLabelWidth = MAXFLOAT; 345 | } 346 | 347 | /* this is used when labels wrap text and the line 348 | * should be in the middle of the first row */ 349 | CGFloat singleRowHeight = [SCLineChart sizeOfString:@"Test" 350 | withWidth:MAXFLOAT 351 | font:self.legendFont ? self.legendFont : [UIFont systemFontOfSize:12.0f]].height; 352 | 353 | NSUInteger counter = 0; 354 | NSUInteger rowWidth = 0; 355 | NSUInteger rowMaxHeight = 0; 356 | 357 | for (SCPieChartDataItem *pdata in self.items) { 358 | /* Expected label size*/ 359 | CGSize labelsize = [SCLineChart sizeOfString:pdata.textDescription 360 | withWidth:maxLabelWidth 361 | font:self.legendFont ? self.legendFont : [UIFont systemFontOfSize:12.0f]]; 362 | 363 | if ((rowWidth + labelsize.width + beforeLabel > mWidth)&&(self.legendStyle == PNLegendItemStyleSerial)) { 364 | rowWidth = 0; 365 | x = 0; 366 | y += rowMaxHeight; 367 | rowMaxHeight = 0; 368 | } 369 | rowWidth += labelsize.width + beforeLabel; 370 | totalWidth = self.legendStyle == PNLegendItemStyleSerial ? fmaxf(rowWidth, totalWidth) : fmaxf(totalWidth, labelsize.width + beforeLabel); 371 | // Add inflexion type 372 | [legendViews addObject:[self drawInflexion:legendCircle * .6 373 | center:CGPointMake(x + legendCircle / 2, y + singleRowHeight / 2) 374 | andColor:pdata.color]]; 375 | 376 | 377 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x + beforeLabel, y, labelsize.width, labelsize.height)]; 378 | label.text = pdata.textDescription; 379 | label.textColor = self.legendFontColor ? self.legendFontColor : [UIColor blackColor]; 380 | label.font = self.legendFont ? self.legendFont : [UIFont systemFontOfSize:12.0f]; 381 | label.lineBreakMode = NSLineBreakByWordWrapping; 382 | label.numberOfLines = 0; 383 | 384 | 385 | rowMaxHeight = fmaxf(rowMaxHeight, labelsize.height); 386 | x += self.legendStyle == PNLegendItemStyleStacked ? 0 : labelsize.width + beforeLabel; 387 | y += self.legendStyle == PNLegendItemStyleStacked ? labelsize.height : 0; 388 | 389 | 390 | totalHeight = self.legendStyle == PNLegendItemStyleSerial ? fmaxf(totalHeight, rowMaxHeight + y) : totalHeight + labelsize.height; 391 | [legendViews addObject:label]; 392 | counter ++; 393 | } 394 | 395 | UIView *legend = [[UIView alloc] initWithFrame:CGRectMake(0, 0, totalWidth, totalHeight)]; 396 | 397 | for (UIView* v in legendViews) { 398 | [legend addSubview:v]; 399 | } 400 | return legend; 401 | } 402 | 403 | 404 | - (UIImageView*)drawInflexion:(CGFloat)size center:(CGPoint)center andColor:(UIColor*)color 405 | { 406 | //Make the size a little bigger so it includes also border stroke 407 | CGSize aSize = CGSizeMake(size, size); 408 | 409 | 410 | UIGraphicsBeginImageContextWithOptions(aSize, NO, 0.0); 411 | CGContextRef context = UIGraphicsGetCurrentContext(); 412 | 413 | CGContextAddArc(context, size/2, size/ 2, size/2, 0, M_PI*2, YES); 414 | 415 | 416 | //Set some fill color 417 | CGContextSetFillColorWithColor(context, color.CGColor); 418 | 419 | //Finally draw 420 | CGContextDrawPath(context, kCGPathFill); 421 | 422 | //now get the image from the context 423 | UIImage *squareImage = UIGraphicsGetImageFromCurrentImageContext(); 424 | 425 | UIGraphicsEndImageContext(); 426 | 427 | //// Translate origin 428 | CGFloat originX = center.x - (size) / 2.0; 429 | CGFloat originY = center.y - (size) / 2.0; 430 | 431 | UIImageView *squareImageView = [[UIImageView alloc]initWithImage:squareImage]; 432 | [squareImageView setFrame:CGRectMake(originX, originY, size, size)]; 433 | return squareImageView; 434 | } 435 | 436 | - (void)updateChartByNumbers:(NSArray *)numbers { 437 | for (SCPieChartDataItem *item in self.items) { 438 | NSInteger index = [self.items indexOfObject:item]; 439 | if (index >= numbers.count) { 440 | break; 441 | } 442 | item.value = [numbers[index] integerValue]; 443 | } 444 | [self strokeChart]; 445 | } 446 | 447 | @end 448 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCPieChartDataItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // PNPieChartDataItem.h 3 | // PNChartDemo 4 | // 5 | // Created by Hang Zhang on 14-5-5. 6 | // Copyright (c) 2014年 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SCPieChartDataItem : NSObject 13 | 14 | + (instancetype)dataItemWithValue:(CGFloat)value 15 | color:(UIColor*)color; 16 | 17 | + (instancetype)dataItemWithValue:(CGFloat)value 18 | color:(UIColor*)color 19 | description:(NSString *)description; 20 | 21 | @property (nonatomic) CGFloat value; 22 | @property (nonatomic) UIColor *color; 23 | @property (nonatomic) NSString *textDescription; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCPieChartDataItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // PNPieChartDataItem.m 3 | // PNChartDemo 4 | // 5 | // Created by Hang Zhang on 14-5-5. 6 | // Copyright (c) 2014年 kevinzhow. All rights reserved. 7 | // 8 | 9 | #import "SCPieChartDataItem.h" 10 | #import 11 | 12 | @implementation SCPieChartDataItem 13 | 14 | 15 | + (instancetype)dataItemWithValue:(CGFloat)value 16 | color:(UIColor*)color{ 17 | SCPieChartDataItem *item = [SCPieChartDataItem new]; 18 | item.value = value; 19 | item.color = color; 20 | return item; 21 | } 22 | 23 | + (instancetype)dataItemWithValue:(CGFloat)value 24 | color:(UIColor*)color 25 | description:(NSString *)description { 26 | SCPieChartDataItem *item = [SCPieChartDataItem dataItemWithValue:value color:color]; 27 | item.textDescription = description; 28 | return item; 29 | } 30 | 31 | - (void)setValue:(CGFloat)value{ 32 | NSAssert(value >= 0, @"value should >= 0"); 33 | if (value != _value){ 34 | _value = value; 35 | } 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // UUTool.h 3 | // DataCenter 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCTool : NSObject 12 | /** 13 | * 返回图表适合分的行数(4|5|6行) 14 | * 15 | * @param rangeMax 数组中的最大值 16 | * 17 | * @return 图表适合分的行数 18 | */ 19 | +(NSInteger)rowCountWithValueMax:(CGFloat)valueMax; 20 | /** 21 | * 返回适合图表分布的范围内最大值 22 | * 23 | * @param rangeMax 数组中的最大值 24 | * 25 | * @return 图表适合的范围内最大值 26 | */ 27 | +(CGFloat)rangeMaxWithValueMax:(CGFloat)valueMax; 28 | @end 29 | -------------------------------------------------------------------------------- /SCChart/SCChart/SCTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // UUTool.m 3 | // DataCenter 4 | // 5 | // Created by 2014-763 on 15/3/12. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCTool.h" 10 | 11 | @implementation SCTool 12 | 13 | +(NSInteger)rowCountWithValueMax:(CGFloat)valueMax { 14 | NSInteger number1 = 0; 15 | NSInteger number2 = 0; 16 | NSInteger number3 = 0; 17 | NSInteger rowCount = 0; 18 | NSString *valueMaxStr = [NSString stringWithFormat:@"%f",valueMax]; 19 | for (int i = 0; i < valueMaxStr.length; i++) { 20 | NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; 21 | if (![c isEqualToString:@"0"]&&![c isEqualToString:@"."]) { 22 | if (number1 == 0) { 23 | number1 = [c integerValue]; 24 | if (number1 > 2) { 25 | break; 26 | } 27 | } else if (number2 == 0) { 28 | number2 = [c integerValue]; 29 | if (number2 != 2) { 30 | break; 31 | } 32 | } else if (number3 == 0) { 33 | number3 = [c integerValue]; 34 | break; 35 | } 36 | } 37 | } 38 | if (number1 > 2) { 39 | switch (number1) { 40 | case 3: 41 | case 6: 42 | case 7: 43 | case 9: 44 | rowCount = 4; 45 | break; 46 | case 4: 47 | case 8: 48 | rowCount = 5; 49 | break; 50 | case 5: 51 | rowCount = 6; 52 | default: 53 | break; 54 | } 55 | } else if (number1 <= 2) { 56 | if (number1 == 1) { 57 | switch (number2) { 58 | case 0: 59 | case 1: 60 | case 2: 61 | { 62 | if (number3 < 5) { 63 | rowCount = 5; 64 | } else if (number3 >= 5) { 65 | rowCount = 6; 66 | } 67 | break; 68 | } 69 | case 3: 70 | case 4: 71 | rowCount = 6; 72 | break; 73 | case 5: 74 | case 6: 75 | case 7: 76 | case 8: 77 | case 9: 78 | rowCount = 4; 79 | break; 80 | default: 81 | break; 82 | } 83 | } else if (number1 == 2) { 84 | switch (number2) { 85 | case 0: 86 | case 1: 87 | case 2: 88 | case 3: 89 | case 4: 90 | rowCount = 5; 91 | break; 92 | case 5: 93 | case 6: 94 | case 7: 95 | case 8: 96 | case 9: 97 | rowCount = 6; 98 | break; 99 | default: 100 | break; 101 | } 102 | } 103 | } 104 | return rowCount; 105 | } 106 | 107 | +(CGFloat)rangeMaxWithValueMax:(CGFloat)valueMax { 108 | NSInteger number1 = 0; 109 | NSInteger number2 = 0; 110 | NSInteger number3 = 0; 111 | CGFloat rangeMax = 0.0; 112 | NSString *valueMaxStr = [NSString stringWithFormat:@"%f",valueMax]; 113 | for (int i = 0; i < valueMaxStr.length; i++) { 114 | NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; 115 | if (![c isEqualToString:@"0"]&&![c isEqualToString:@"."]) { 116 | if (number1 == 0) { 117 | number1 = [c integerValue]; 118 | if (number1 > 2) { 119 | break; 120 | } 121 | } else if (number2 == 0) { 122 | number2 = [c integerValue]; 123 | if (number2 != 2) { 124 | break; 125 | } 126 | } else if (number3 == 0) { 127 | number3 = [c integerValue]; 128 | break; 129 | } 130 | } 131 | } 132 | if (number1 > 2) { 133 | switch (number1) { 134 | case 3: 135 | rangeMax = 4; 136 | break; 137 | case 4: 138 | rangeMax = 5; 139 | break; 140 | case 5: 141 | rangeMax = 6; 142 | break; 143 | case 6: 144 | case 7: 145 | rangeMax = 8; 146 | break; 147 | case 8: 148 | case 9: 149 | rangeMax = 10; 150 | break; 151 | default: 152 | break; 153 | } 154 | } else if (number1 <= 2) { 155 | if (number1 == 1) { 156 | switch (number2) { 157 | case 0: 158 | case 1: 159 | case 2: 160 | { 161 | if (number3 < 5) { 162 | rangeMax = 1.25; 163 | } else if (number3 >= 5) { 164 | rangeMax = 1.5; 165 | } 166 | break; 167 | } 168 | case 3: 169 | case 4: 170 | rangeMax = 1.5; 171 | break; 172 | case 5: 173 | case 6: 174 | case 7: 175 | case 8: 176 | case 9: 177 | rangeMax = 2.0; 178 | break; 179 | default: 180 | break; 181 | } 182 | } else if (number1 == 2) { 183 | switch (number2) { 184 | case 0: 185 | case 1: 186 | case 2: 187 | case 3: 188 | case 4: 189 | rangeMax = 2.5; 190 | break; 191 | case 5: 192 | case 6: 193 | case 7: 194 | case 8: 195 | case 9: 196 | rangeMax = 3.0; 197 | break; 198 | default: 199 | break; 200 | } 201 | } 202 | } 203 | CGFloat n = 1; 204 | for (int i = 0; i < valueMaxStr.length; i++) { 205 | if (valueMax > 1) { 206 | NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; 207 | if (![c isEqualToString:@"."]) { 208 | n = n*10; 209 | } else { 210 | n = n/10; 211 | break; 212 | } 213 | } else { 214 | NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; 215 | if ([c isEqualToString:@"0"]) { 216 | n = n/10; 217 | } else if (![c isEqualToString:@"."]){ 218 | break; 219 | } 220 | } 221 | } 222 | return rangeMax*n; 223 | } 224 | 225 | @end 226 | -------------------------------------------------------------------------------- /SCChart/SCChart/UICountingLabel.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | typedef enum { 5 | UILabelCountingMethodEaseInOut, 6 | UILabelCountingMethodEaseIn, 7 | UILabelCountingMethodEaseOut, 8 | UILabelCountingMethodLinear 9 | } UILabelCountingMethod; 10 | 11 | typedef NSString* (^UICountingLabelFormatBlock)(float value); 12 | typedef NSAttributedString* (^UICountingLabelAttributedFormatBlock)(float value); 13 | 14 | @interface UICountingLabel : UILabel 15 | 16 | @property (nonatomic, strong) NSString *format; 17 | @property (nonatomic, assign) UILabelCountingMethod method; 18 | @property (nonatomic, assign) NSTimeInterval animationDuration; 19 | 20 | @property (nonatomic, copy) UICountingLabelFormatBlock formatBlock; 21 | @property (nonatomic, copy) UICountingLabelAttributedFormatBlock attributedFormatBlock; 22 | @property (nonatomic, copy) void (^completionBlock)(); 23 | 24 | -(void)countFrom:(float)startValue to:(float)endValue; 25 | -(void)countFrom:(float)startValue to:(float)endValue withDuration:(NSTimeInterval)duration; 26 | 27 | -(void)countFromCurrentValueTo:(float)endValue; 28 | -(void)countFromCurrentValueTo:(float)endValue withDuration:(NSTimeInterval)duration; 29 | 30 | -(void)countFromZeroTo:(float)endValue; 31 | -(void)countFromZeroTo:(float)endValue withDuration:(NSTimeInterval)duration; 32 | 33 | - (CGFloat)currentValue; 34 | 35 | @end 36 | 37 | -------------------------------------------------------------------------------- /SCChart/SCChart/UICountingLabel.m: -------------------------------------------------------------------------------- 1 | #import "UICountingLabel.h" 2 | 3 | #if !__has_feature(objc_arc) 4 | #error UICountingLabel is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 5 | #endif 6 | 7 | #pragma mark - UILabelCounter 8 | 9 | // This whole class & subclasses are private to UICountingLabel, which is why they are declared here in the .m file 10 | 11 | @interface UILabelCounter : NSObject 12 | 13 | -(float)update:(float)t; 14 | 15 | @property float rate; 16 | 17 | @end 18 | 19 | @interface UILabelCounterLinear : UILabelCounter 20 | 21 | @end 22 | 23 | @interface UILabelCounterEaseIn : UILabelCounter 24 | 25 | @end 26 | 27 | @interface UILabelCounterEaseOut : UILabelCounter 28 | 29 | @end 30 | 31 | @interface UILabelCounterEaseInOut : UILabelCounter 32 | 33 | @end 34 | 35 | @implementation UILabelCounter 36 | 37 | -(float)update:(float)t{ 38 | return 0; 39 | } 40 | 41 | @end 42 | 43 | @implementation UILabelCounterLinear 44 | 45 | -(float)update:(float)t 46 | { 47 | return t; 48 | } 49 | 50 | @end 51 | 52 | @implementation UILabelCounterEaseIn 53 | 54 | -(float)update:(float)t 55 | { 56 | return powf(t, self.rate); 57 | } 58 | 59 | @end 60 | 61 | @implementation UILabelCounterEaseOut 62 | 63 | -(float)update:(float)t{ 64 | return 1.0-powf((1.0-t), self.rate); 65 | } 66 | 67 | @end 68 | 69 | @implementation UILabelCounterEaseInOut 70 | 71 | -(float) update: (float) t 72 | { 73 | int sign =1; 74 | int r = (int) self.rate; 75 | if (r % 2 == 0) 76 | sign = -1; 77 | t *= 2; 78 | if (t < 1) 79 | return 0.5f * powf (t, self.rate); 80 | else 81 | return sign*0.5f * (powf (t-2, self.rate) + sign*2); 82 | } 83 | 84 | @end 85 | 86 | #pragma mark - UICountingLabel 87 | 88 | @interface UICountingLabel () 89 | 90 | @property float startingValue; 91 | @property float destinationValue; 92 | @property NSTimeInterval progress; 93 | @property NSTimeInterval lastUpdate; 94 | @property NSTimeInterval totalTime; 95 | @property float easingRate; 96 | 97 | @property (nonatomic, weak) NSTimer *timer; 98 | @property (nonatomic, strong) UILabelCounter *counter; 99 | 100 | @end 101 | 102 | @implementation UICountingLabel 103 | 104 | -(void)countFrom:(float)value to:(float)endValue { 105 | 106 | if (self.animationDuration == 0.0f) { 107 | self.animationDuration = 2.0f; 108 | } 109 | 110 | [self countFrom:value to:endValue withDuration:self.animationDuration]; 111 | } 112 | 113 | -(void)countFrom:(float)startValue to:(float)endValue withDuration:(NSTimeInterval)duration { 114 | 115 | self.startingValue = startValue; 116 | self.destinationValue = endValue; 117 | 118 | // remove any (possible) old timers 119 | [self.timer invalidate]; 120 | self.timer = nil; 121 | 122 | if (duration == 0.0) { 123 | // No animation 124 | [self setTextValue:endValue]; 125 | [self runCompletionBlock]; 126 | return; 127 | } 128 | 129 | self.easingRate = 3.0f; 130 | self.progress = 0; 131 | self.totalTime = duration; 132 | self.lastUpdate = [NSDate timeIntervalSinceReferenceDate]; 133 | 134 | if(self.format == nil) 135 | self.format = @"%f"; 136 | 137 | switch(self.method) 138 | { 139 | case UILabelCountingMethodLinear: 140 | self.counter = [[UILabelCounterLinear alloc] init]; 141 | break; 142 | case UILabelCountingMethodEaseIn: 143 | self.counter = [[UILabelCounterEaseIn alloc] init]; 144 | break; 145 | case UILabelCountingMethodEaseOut: 146 | self.counter = [[UILabelCounterEaseOut alloc] init]; 147 | break; 148 | case UILabelCountingMethodEaseInOut: 149 | self.counter = [[UILabelCounterEaseInOut alloc] init]; 150 | break; 151 | } 152 | 153 | self.counter.rate = 3.0f; 154 | 155 | NSTimer *timer = [NSTimer timerWithTimeInterval:(1.0f/30.0f) target:self selector:@selector(updateValue:) userInfo:nil repeats:YES]; 156 | [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 157 | [[NSRunLoop mainRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]; 158 | self.timer = timer; 159 | } 160 | 161 | - (void)countFromCurrentValueTo:(float)endValue { 162 | [self countFrom:[self currentValue] to:endValue]; 163 | } 164 | 165 | - (void)countFromCurrentValueTo:(float)endValue withDuration:(NSTimeInterval)duration { 166 | [self countFrom:[self currentValue] to:endValue withDuration:duration]; 167 | } 168 | 169 | - (void)countFromZeroTo:(float)endValue { 170 | [self countFrom:0.0f to:endValue]; 171 | } 172 | 173 | - (void)countFromZeroTo:(float)endValue withDuration:(NSTimeInterval)duration { 174 | [self countFrom:0.0f to:endValue withDuration:duration]; 175 | } 176 | 177 | - (void)updateValue:(NSTimer *)timer { 178 | 179 | // update progress 180 | NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; 181 | self.progress += now - self.lastUpdate; 182 | self.lastUpdate = now; 183 | 184 | if (self.progress >= self.totalTime) { 185 | [self.timer invalidate]; 186 | self.timer = nil; 187 | self.progress = self.totalTime; 188 | } 189 | 190 | [self setTextValue:[self currentValue]]; 191 | 192 | if (self.progress == self.totalTime) { 193 | [self runCompletionBlock]; 194 | } 195 | } 196 | 197 | - (void)setTextValue:(float)value 198 | { 199 | if (self.attributedFormatBlock != nil) { 200 | self.attributedText = self.attributedFormatBlock(value); 201 | } 202 | else if(self.formatBlock != nil) 203 | { 204 | self.text = self.formatBlock(value); 205 | } 206 | else 207 | { 208 | // check if counting with ints - cast to int 209 | if([self.format rangeOfString:@"%(.*)d" options:NSRegularExpressionSearch].location != NSNotFound || [self.format rangeOfString:@"%(.*)i"].location != NSNotFound ) 210 | { 211 | self.text = [NSString stringWithFormat:self.format,(int)value]; 212 | } 213 | else 214 | { 215 | self.text = [NSString stringWithFormat:self.format,value]; 216 | } 217 | } 218 | } 219 | 220 | - (void)setFormat:(NSString *)format { 221 | _format = format; 222 | // update label with new format 223 | [self setTextValue:self.currentValue]; 224 | } 225 | 226 | - (void)runCompletionBlock { 227 | 228 | if (self.completionBlock) { 229 | self.completionBlock(); 230 | self.completionBlock = nil; 231 | } 232 | } 233 | 234 | - (CGFloat)currentValue { 235 | 236 | if (self.progress >= self.totalTime) { 237 | return self.destinationValue; 238 | } 239 | 240 | CGFloat percent = self.progress / self.totalTime; 241 | CGFloat updateVal = [self.counter update:percent]; 242 | return self.startingValue + (updateVal * (self.destinationValue - self.startingValue)); 243 | } 244 | 245 | @end 246 | -------------------------------------------------------------------------------- /SCChart/SCChartCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.h 3 | // UUChartView 4 | // 5 | // Created by shake on 15/1/4. 6 | // Copyright (c) 2015年 uyiuyao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCChartCell : UITableViewCell 12 | 13 | - (void)configUI:(NSIndexPath *)indexPath; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SCChart/SCChartCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.m 3 | // UUChartView 4 | // 5 | // Created by shake on 15/1/4. 6 | // Copyright (c) 2015年 uyiuyao. All rights reserved. 7 | // 8 | 9 | #import "SCChartCell.h" 10 | #import "SCChart.h" 11 | 12 | @interface SCChartCell () 13 | { 14 | NSIndexPath *path; 15 | SCChart *chartView; 16 | } 17 | @end 18 | 19 | @implementation SCChartCell 20 | 21 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 22 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 23 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 24 | [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; 25 | btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; 26 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 27 | btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); 28 | [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; 29 | [self addSubview:btn]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)btnPressed:(id)sender { 35 | [chartView strokeChart]; 36 | } 37 | 38 | - (void)configUI:(NSIndexPath *)indexPath { 39 | if (chartView) { 40 | [chartView removeFromSuperview]; 41 | chartView = nil; 42 | } 43 | path = indexPath; 44 | chartView = [[SCChart alloc] initwithSCChartDataFrame:CGRectMake(10, (self.frame.size.height-150)/2, [UIScreen mainScreen].bounds.size.width - 20, 150) 45 | withSource:self 46 | withStyle:SCChartLineStyle]; 47 | [chartView showInView:self.contentView]; 48 | } 49 | 50 | - (NSArray *)getXTitles:(int)num { 51 | NSMutableArray *xTitles = [NSMutableArray array]; 52 | for (int i=0; i 10 | 11 | @interface SCCircleCell : UITableViewCell 12 | 13 | - (void)configUI:(NSIndexPath *)indexPath; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SCChart/SCCircleCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCCircleCell.m 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/24. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCCircleCell.h" 10 | #import "SCChart.h" 11 | 12 | @interface SCCircleCell() 13 | { 14 | SCCircleChart *chartView; 15 | } 16 | @end 17 | 18 | @implementation SCCircleCell 19 | 20 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 21 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 22 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 23 | [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; 24 | btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; 25 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 26 | btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); 27 | [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; 28 | [self addSubview:btn]; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)btnPressed:(id)sender { 34 | CGFloat num = arc4random_uniform(60); 35 | [chartView updateChartByCurrent:@(num)]; 36 | } 37 | 38 | - (void)configUI:(NSIndexPath *)indexPath { 39 | if (chartView) { 40 | [chartView removeFromSuperview]; 41 | chartView = nil; 42 | } 43 | chartView = [[SCCircleChart alloc] initWithFrame:CGRectMake(0, (self.frame.size.height-100)/2, SCREEN_WIDTH, 100.0) 44 | total:@100 45 | current:@60 46 | clockwise:YES]; 47 | [chartView setStrokeColor:SCBlue]; 48 | chartView.chartType = SCChartFormatTypeNone; 49 | chartView.format = @"无线端\n%d%%"; 50 | [chartView strokeChart]; 51 | [self addSubview:chartView]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /SCChart/SCPieCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCPieCell.h 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/24. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCPieCell : UITableViewCell 12 | 13 | - (void)configUI:(NSIndexPath *)indexPath; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SCChart/SCPieCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCPieCell.m 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/24. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCPieCell.h" 10 | #import "SCChart.h" 11 | 12 | @interface SCPieCell() 13 | { 14 | SCPieChart *chartView; 15 | } 16 | @end 17 | 18 | @implementation SCPieCell 19 | 20 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 21 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 22 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 23 | [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; 24 | btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; 25 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 26 | btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); 27 | [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; 28 | [self addSubview:btn]; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)btnPressed:(id)sender { 34 | NSMutableArray *ary = [NSMutableArray array]; 35 | for (NSInteger i = 0; i < 3; i++) { 36 | CGFloat num = arc4random_uniform(100); 37 | NSString *str = [NSString stringWithFormat:@"%f",num]; 38 | [ary addObject:str]; 39 | } 40 | [chartView updateChartByNumbers:ary]; 41 | } 42 | 43 | - (void)configUI:(NSIndexPath *)indexPath { 44 | if (chartView) { 45 | [chartView removeFromSuperview]; 46 | chartView = nil; 47 | } 48 | NSArray *items = @[[SCPieChartDataItem dataItemWithValue:10 color:SCRed description:@"A"], 49 | [SCPieChartDataItem dataItemWithValue:20 color:SCBlue description:@"B"], 50 | [SCPieChartDataItem dataItemWithValue:40 color:SCGreen description:@"C"], 51 | ]; 52 | 53 | chartView = [[SCPieChart alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-150)/2, (self.frame.size.height-150)/2, 150.0, 150.0) items:items]; 54 | chartView.descriptionTextColor = [UIColor whiteColor]; 55 | chartView.descriptionTextFont = [UIFont fontWithName:@"Avenir-Medium" size:12.0]; 56 | [chartView strokeChart]; 57 | [self addSubview:chartView]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /SCChart/SCViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCViewController.h 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SCChart/SCViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCViewController.m 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import "SCViewController.h" 10 | #import "SCChartCell.h" 11 | #import "SCBarCell.h" 12 | #import "SCCircleCell.h" 13 | #import "SCPieCell.h" 14 | 15 | @interface SCViewController () 16 | 17 | @end 18 | 19 | @implementation SCViewController 20 | static NSString *reuseIdentifierChart = @"SCChartCell"; 21 | static NSString *reuseIdentifierBar = @"SCBarCell"; 22 | static NSString *reuseIdentifierCircle = @"SCCircleCell"; 23 | static NSString *reuseIdentifierPie = @"SCPieCell"; 24 | 25 | - (BOOL)prefersStatusBarHidden { 26 | return YES; 27 | } 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; 32 | tableView.delegate = self; 33 | tableView.dataSource = self; 34 | [tableView registerClass:[SCChartCell class] forCellReuseIdentifier:reuseIdentifierChart]; 35 | [tableView registerClass:[SCBarCell class] forCellReuseIdentifier:reuseIdentifierBar]; 36 | [tableView registerClass:[SCCircleCell class] forCellReuseIdentifier:reuseIdentifierCircle]; 37 | [tableView registerClass:[SCPieCell class] forCellReuseIdentifier:reuseIdentifierPie]; 38 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 39 | [self.view addSubview:tableView]; 40 | 41 | } 42 | 43 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 44 | return 4; 45 | } 46 | 47 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 48 | switch (section) { 49 | case 0: 50 | return 3; 51 | break; 52 | case 1: 53 | return 2; 54 | break; 55 | case 2: 56 | return 1; 57 | break; 58 | case 3: 59 | return 1; 60 | break; 61 | default: 62 | return 0; 63 | break; 64 | } 65 | } 66 | 67 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 68 | switch (indexPath.section) { 69 | case 0: 70 | { 71 | SCChartCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierChart forIndexPath:indexPath]; 72 | if (!cell) { 73 | cell = [[SCChartCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierChart]; 74 | } 75 | [cell configUI:indexPath]; 76 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 77 | return cell; 78 | } 79 | break; 80 | 81 | case 1: 82 | { 83 | SCBarCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierBar forIndexPath:indexPath]; 84 | if (!cell) { 85 | cell = [[SCBarCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierBar]; 86 | } 87 | [cell configUI:indexPath]; 88 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 89 | return cell; 90 | } 91 | break; 92 | 93 | case 2: 94 | { 95 | SCChartCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierCircle forIndexPath:indexPath]; 96 | if (!cell) { 97 | cell = [[SCChartCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierCircle]; 98 | } 99 | [cell configUI:indexPath]; 100 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 101 | return cell; 102 | } 103 | break; 104 | 105 | case 3: 106 | { 107 | SCPieCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierPie forIndexPath:indexPath]; 108 | if (!cell) { 109 | cell = [[SCPieCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierPie]; 110 | } 111 | [cell configUI:indexPath]; 112 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 113 | return cell; 114 | } 115 | break; 116 | 117 | default: 118 | break; 119 | } 120 | return nil; 121 | } 122 | 123 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 124 | return 200; 125 | } 126 | 127 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 128 | CGRect frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width , 30); 129 | UILabel *label = [[UILabel alloc]initWithFrame:frame]; 130 | label.font = [UIFont systemFontOfSize:14]; 131 | label.backgroundColor = [[UIColor lightGrayColor]colorWithAlphaComponent:0.3]; 132 | switch (section) { 133 | case 0: 134 | label.text = @"折线图"; 135 | break; 136 | case 1: 137 | label.text = @"柱状图"; 138 | break; 139 | case 2: 140 | label.text = @"圆形图"; 141 | break; 142 | case 3: 143 | label.text = @"圆饼图"; 144 | break; 145 | default: 146 | break; 147 | } 148 | label.textColor = [UIColor colorWithRed:0.257 green:0.650 blue:0.478 alpha:1.000]; 149 | label.textAlignment = NSTextAlignmentCenter; 150 | return label; 151 | } 152 | 153 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 154 | return 30; 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /SCChart/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SCChart 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SCChartTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.meilishuo.bizfe.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SCChartTests/SCChartTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCChartTests.m 3 | // SCChartTests 4 | // 5 | // Created by 2014-763 on 15/3/13. 6 | // Copyright (c) 2015年 meilishuo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SCChartTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation SCChartTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------