├── .DS_Store ├── README.md ├── TLChart.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── hello.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── hello.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist └── TLChart ├── .DS_Store ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── PrefixHeader.pch ├── TLChartTool ├── TLChartDoubleHistogramView.h ├── TLChartDoubleHistogramView.m ├── TLChartRateView.h ├── TLChartRateView.m ├── TLChartRateView1.h ├── TLChartRateView1.m ├── TLChartSingleHistogramView.h ├── TLChartSingleHistogramView.m ├── TLChartTableView.h └── TLChartTableView.m ├── ViewController.h ├── ViewController.m ├── ViewController1.h ├── ViewController1.m └── main.m /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepiec/TLChart/a6f55c23f53907ea4bb0d58a687957399ad84115/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 文档地址 3 | 4 | [简书](https://www.jianshu.com/p/9953bc71b039) 5 | -------------------------------------------------------------------------------- /TLChart.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CE16B18A228131EA00721F5F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B189228131EA00721F5F /* AppDelegate.m */; }; 11 | CE16B18D228131EA00721F5F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B18C228131EA00721F5F /* ViewController.m */; }; 12 | CE16B190228131EA00721F5F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE16B18E228131EA00721F5F /* Main.storyboard */; }; 13 | CE16B192228131EC00721F5F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE16B191228131EC00721F5F /* Assets.xcassets */; }; 14 | CE16B195228131EC00721F5F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE16B193228131EC00721F5F /* LaunchScreen.storyboard */; }; 15 | CE16B198228131EC00721F5F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B197228131EC00721F5F /* main.m */; }; 16 | CE16B1A12281324A00721F5F /* ViewController1.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B1A02281324A00721F5F /* ViewController1.m */; }; 17 | CE16B1AD2281330A00721F5F /* TLChartSingleHistogramView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B1A32281330A00721F5F /* TLChartSingleHistogramView.m */; }; 18 | CE16B1AE2281330A00721F5F /* TLChartRateView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B1A42281330A00721F5F /* TLChartRateView.m */; }; 19 | CE16B1AF2281330A00721F5F /* TLChartDoubleHistogramView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B1A52281330A00721F5F /* TLChartDoubleHistogramView.m */; }; 20 | CE16B1B02281330A00721F5F /* TLChartRateView1.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B1A72281330A00721F5F /* TLChartRateView1.m */; }; 21 | CE16B1B12281330A00721F5F /* TLChartTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE16B1AB2281330A00721F5F /* TLChartTableView.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | CE16B185228131EA00721F5F /* TLChart.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TLChart.app; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | CE16B188228131EA00721F5F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 27 | CE16B189228131EA00721F5F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 28 | CE16B18B228131EA00721F5F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 29 | CE16B18C228131EA00721F5F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 30 | CE16B18F228131EA00721F5F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 31 | CE16B191228131EC00721F5F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 32 | CE16B194228131EC00721F5F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 33 | CE16B196228131EC00721F5F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | CE16B197228131EC00721F5F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | CE16B19E2281322600721F5F /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 36 | CE16B19F2281324A00721F5F /* ViewController1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController1.h; sourceTree = ""; }; 37 | CE16B1A02281324A00721F5F /* ViewController1.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController1.m; sourceTree = ""; }; 38 | CE16B1A32281330A00721F5F /* TLChartSingleHistogramView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TLChartSingleHistogramView.m; sourceTree = ""; }; 39 | CE16B1A42281330A00721F5F /* TLChartRateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TLChartRateView.m; sourceTree = ""; }; 40 | CE16B1A52281330A00721F5F /* TLChartDoubleHistogramView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TLChartDoubleHistogramView.m; sourceTree = ""; }; 41 | CE16B1A62281330A00721F5F /* TLChartTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLChartTableView.h; sourceTree = ""; }; 42 | CE16B1A72281330A00721F5F /* TLChartRateView1.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TLChartRateView1.m; sourceTree = ""; }; 43 | CE16B1A82281330A00721F5F /* TLChartSingleHistogramView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLChartSingleHistogramView.h; sourceTree = ""; }; 44 | CE16B1A92281330A00721F5F /* TLChartDoubleHistogramView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLChartDoubleHistogramView.h; sourceTree = ""; }; 45 | CE16B1AA2281330A00721F5F /* TLChartRateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLChartRateView.h; sourceTree = ""; }; 46 | CE16B1AB2281330A00721F5F /* TLChartTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TLChartTableView.m; sourceTree = ""; }; 47 | CE16B1AC2281330A00721F5F /* TLChartRateView1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLChartRateView1.h; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | CE16B182228131EA00721F5F /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | CE16B17C228131EA00721F5F = { 62 | isa = PBXGroup; 63 | children = ( 64 | CE16B187228131EA00721F5F /* TLChart */, 65 | CE16B186228131EA00721F5F /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | CE16B186228131EA00721F5F /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | CE16B185228131EA00721F5F /* TLChart.app */, 73 | ); 74 | name = Products; 75 | sourceTree = ""; 76 | }; 77 | CE16B187228131EA00721F5F /* TLChart */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | CE16B1A22281330A00721F5F /* TLChartTool */, 81 | CE16B188228131EA00721F5F /* AppDelegate.h */, 82 | CE16B189228131EA00721F5F /* AppDelegate.m */, 83 | CE16B18B228131EA00721F5F /* ViewController.h */, 84 | CE16B18C228131EA00721F5F /* ViewController.m */, 85 | CE16B19F2281324A00721F5F /* ViewController1.h */, 86 | CE16B1A02281324A00721F5F /* ViewController1.m */, 87 | CE16B18E228131EA00721F5F /* Main.storyboard */, 88 | CE16B191228131EC00721F5F /* Assets.xcassets */, 89 | CE16B193228131EC00721F5F /* LaunchScreen.storyboard */, 90 | CE16B196228131EC00721F5F /* Info.plist */, 91 | CE16B197228131EC00721F5F /* main.m */, 92 | CE16B19E2281322600721F5F /* PrefixHeader.pch */, 93 | ); 94 | path = TLChart; 95 | sourceTree = ""; 96 | }; 97 | CE16B1A22281330A00721F5F /* TLChartTool */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | CE16B1AA2281330A00721F5F /* TLChartRateView.h */, 101 | CE16B1A42281330A00721F5F /* TLChartRateView.m */, 102 | CE16B1AC2281330A00721F5F /* TLChartRateView1.h */, 103 | CE16B1A72281330A00721F5F /* TLChartRateView1.m */, 104 | CE16B1A62281330A00721F5F /* TLChartTableView.h */, 105 | CE16B1AB2281330A00721F5F /* TLChartTableView.m */, 106 | CE16B1A82281330A00721F5F /* TLChartSingleHistogramView.h */, 107 | CE16B1A32281330A00721F5F /* TLChartSingleHistogramView.m */, 108 | CE16B1A92281330A00721F5F /* TLChartDoubleHistogramView.h */, 109 | CE16B1A52281330A00721F5F /* TLChartDoubleHistogramView.m */, 110 | ); 111 | path = TLChartTool; 112 | sourceTree = ""; 113 | }; 114 | /* End PBXGroup section */ 115 | 116 | /* Begin PBXNativeTarget section */ 117 | CE16B184228131EA00721F5F /* TLChart */ = { 118 | isa = PBXNativeTarget; 119 | buildConfigurationList = CE16B19B228131EC00721F5F /* Build configuration list for PBXNativeTarget "TLChart" */; 120 | buildPhases = ( 121 | CE16B181228131EA00721F5F /* Sources */, 122 | CE16B182228131EA00721F5F /* Frameworks */, 123 | CE16B183228131EA00721F5F /* Resources */, 124 | ); 125 | buildRules = ( 126 | ); 127 | dependencies = ( 128 | ); 129 | name = TLChart; 130 | productName = TLChart; 131 | productReference = CE16B185228131EA00721F5F /* TLChart.app */; 132 | productType = "com.apple.product-type.application"; 133 | }; 134 | /* End PBXNativeTarget section */ 135 | 136 | /* Begin PBXProject section */ 137 | CE16B17D228131EA00721F5F /* Project object */ = { 138 | isa = PBXProject; 139 | attributes = { 140 | LastUpgradeCheck = 1020; 141 | ORGANIZATIONNAME = tanglei; 142 | TargetAttributes = { 143 | CE16B184228131EA00721F5F = { 144 | CreatedOnToolsVersion = 10.2; 145 | }; 146 | }; 147 | }; 148 | buildConfigurationList = CE16B180228131EA00721F5F /* Build configuration list for PBXProject "TLChart" */; 149 | compatibilityVersion = "Xcode 9.3"; 150 | developmentRegion = en; 151 | hasScannedForEncodings = 0; 152 | knownRegions = ( 153 | en, 154 | Base, 155 | ); 156 | mainGroup = CE16B17C228131EA00721F5F; 157 | productRefGroup = CE16B186228131EA00721F5F /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | CE16B184228131EA00721F5F /* TLChart */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | CE16B183228131EA00721F5F /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | CE16B195228131EC00721F5F /* LaunchScreen.storyboard in Resources */, 172 | CE16B192228131EC00721F5F /* Assets.xcassets in Resources */, 173 | CE16B190228131EA00721F5F /* Main.storyboard in Resources */, 174 | ); 175 | runOnlyForDeploymentPostprocessing = 0; 176 | }; 177 | /* End PBXResourcesBuildPhase section */ 178 | 179 | /* Begin PBXSourcesBuildPhase section */ 180 | CE16B181228131EA00721F5F /* Sources */ = { 181 | isa = PBXSourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | CE16B1A12281324A00721F5F /* ViewController1.m in Sources */, 185 | CE16B18D228131EA00721F5F /* ViewController.m in Sources */, 186 | CE16B198228131EC00721F5F /* main.m in Sources */, 187 | CE16B1AE2281330A00721F5F /* TLChartRateView.m in Sources */, 188 | CE16B1AD2281330A00721F5F /* TLChartSingleHistogramView.m in Sources */, 189 | CE16B1AF2281330A00721F5F /* TLChartDoubleHistogramView.m in Sources */, 190 | CE16B18A228131EA00721F5F /* AppDelegate.m in Sources */, 191 | CE16B1B12281330A00721F5F /* TLChartTableView.m in Sources */, 192 | CE16B1B02281330A00721F5F /* TLChartRateView1.m in Sources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXSourcesBuildPhase section */ 197 | 198 | /* Begin PBXVariantGroup section */ 199 | CE16B18E228131EA00721F5F /* Main.storyboard */ = { 200 | isa = PBXVariantGroup; 201 | children = ( 202 | CE16B18F228131EA00721F5F /* Base */, 203 | ); 204 | name = Main.storyboard; 205 | sourceTree = ""; 206 | }; 207 | CE16B193228131EC00721F5F /* LaunchScreen.storyboard */ = { 208 | isa = PBXVariantGroup; 209 | children = ( 210 | CE16B194228131EC00721F5F /* Base */, 211 | ); 212 | name = LaunchScreen.storyboard; 213 | sourceTree = ""; 214 | }; 215 | /* End PBXVariantGroup section */ 216 | 217 | /* Begin XCBuildConfiguration section */ 218 | CE16B199228131EC00721F5F /* Debug */ = { 219 | isa = XCBuildConfiguration; 220 | buildSettings = { 221 | ALWAYS_SEARCH_USER_PATHS = NO; 222 | CLANG_ANALYZER_NONNULL = YES; 223 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 224 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 225 | CLANG_CXX_LIBRARY = "libc++"; 226 | CLANG_ENABLE_MODULES = YES; 227 | CLANG_ENABLE_OBJC_ARC = YES; 228 | CLANG_ENABLE_OBJC_WEAK = YES; 229 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 230 | CLANG_WARN_BOOL_CONVERSION = YES; 231 | CLANG_WARN_COMMA = YES; 232 | CLANG_WARN_CONSTANT_CONVERSION = YES; 233 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 234 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 235 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 236 | CLANG_WARN_EMPTY_BODY = YES; 237 | CLANG_WARN_ENUM_CONVERSION = YES; 238 | CLANG_WARN_INFINITE_RECURSION = YES; 239 | CLANG_WARN_INT_CONVERSION = YES; 240 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 241 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 242 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 243 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 244 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 245 | CLANG_WARN_STRICT_PROTOTYPES = YES; 246 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 247 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | CODE_SIGN_IDENTITY = "iPhone Developer"; 251 | COPY_PHASE_STRIP = NO; 252 | DEBUG_INFORMATION_FORMAT = dwarf; 253 | ENABLE_STRICT_OBJC_MSGSEND = YES; 254 | ENABLE_TESTABILITY = YES; 255 | GCC_C_LANGUAGE_STANDARD = gnu11; 256 | GCC_DYNAMIC_NO_PIC = NO; 257 | GCC_NO_COMMON_BLOCKS = YES; 258 | GCC_OPTIMIZATION_LEVEL = 0; 259 | GCC_PREPROCESSOR_DEFINITIONS = ( 260 | "DEBUG=1", 261 | "$(inherited)", 262 | ); 263 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 264 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 265 | GCC_WARN_UNDECLARED_SELECTOR = YES; 266 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 267 | GCC_WARN_UNUSED_FUNCTION = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 270 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 271 | MTL_FAST_MATH = YES; 272 | ONLY_ACTIVE_ARCH = YES; 273 | SDKROOT = iphoneos; 274 | }; 275 | name = Debug; 276 | }; 277 | CE16B19A228131EC00721F5F /* Release */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | ALWAYS_SEARCH_USER_PATHS = NO; 281 | CLANG_ANALYZER_NONNULL = YES; 282 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 283 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 284 | CLANG_CXX_LIBRARY = "libc++"; 285 | CLANG_ENABLE_MODULES = YES; 286 | CLANG_ENABLE_OBJC_ARC = YES; 287 | CLANG_ENABLE_OBJC_WEAK = YES; 288 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 289 | CLANG_WARN_BOOL_CONVERSION = YES; 290 | CLANG_WARN_COMMA = YES; 291 | CLANG_WARN_CONSTANT_CONVERSION = YES; 292 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 294 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 295 | CLANG_WARN_EMPTY_BODY = YES; 296 | CLANG_WARN_ENUM_CONVERSION = YES; 297 | CLANG_WARN_INFINITE_RECURSION = YES; 298 | CLANG_WARN_INT_CONVERSION = YES; 299 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 300 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 301 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 302 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 303 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 304 | CLANG_WARN_STRICT_PROTOTYPES = YES; 305 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 306 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 307 | CLANG_WARN_UNREACHABLE_CODE = YES; 308 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 309 | CODE_SIGN_IDENTITY = "iPhone Developer"; 310 | COPY_PHASE_STRIP = NO; 311 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 312 | ENABLE_NS_ASSERTIONS = NO; 313 | ENABLE_STRICT_OBJC_MSGSEND = YES; 314 | GCC_C_LANGUAGE_STANDARD = gnu11; 315 | GCC_NO_COMMON_BLOCKS = YES; 316 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 317 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 318 | GCC_WARN_UNDECLARED_SELECTOR = YES; 319 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 320 | GCC_WARN_UNUSED_FUNCTION = YES; 321 | GCC_WARN_UNUSED_VARIABLE = YES; 322 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 323 | MTL_ENABLE_DEBUG_INFO = NO; 324 | MTL_FAST_MATH = YES; 325 | SDKROOT = iphoneos; 326 | VALIDATE_PRODUCT = YES; 327 | }; 328 | name = Release; 329 | }; 330 | CE16B19C228131EC00721F5F /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 334 | CODE_SIGN_STYLE = Automatic; 335 | DEVELOPMENT_TEAM = USY78CHE7U; 336 | GCC_PREFIX_HEADER = "$(SRCROOT)/TLChart/PrefixHeader.pch"; 337 | INFOPLIST_FILE = TLChart/Info.plist; 338 | LD_RUNPATH_SEARCH_PATHS = ( 339 | "$(inherited)", 340 | "@executable_path/Frameworks", 341 | ); 342 | PRODUCT_BUNDLE_IDENTIFIER = Mac.TLChart; 343 | PRODUCT_NAME = "$(TARGET_NAME)"; 344 | TARGETED_DEVICE_FAMILY = "1,2"; 345 | }; 346 | name = Debug; 347 | }; 348 | CE16B19D228131EC00721F5F /* Release */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | CODE_SIGN_STYLE = Automatic; 353 | DEVELOPMENT_TEAM = USY78CHE7U; 354 | GCC_PREFIX_HEADER = "$(SRCROOT)/TLChart/PrefixHeader.pch"; 355 | INFOPLIST_FILE = TLChart/Info.plist; 356 | LD_RUNPATH_SEARCH_PATHS = ( 357 | "$(inherited)", 358 | "@executable_path/Frameworks", 359 | ); 360 | PRODUCT_BUNDLE_IDENTIFIER = Mac.TLChart; 361 | PRODUCT_NAME = "$(TARGET_NAME)"; 362 | TARGETED_DEVICE_FAMILY = "1,2"; 363 | }; 364 | name = Release; 365 | }; 366 | /* End XCBuildConfiguration section */ 367 | 368 | /* Begin XCConfigurationList section */ 369 | CE16B180228131EA00721F5F /* Build configuration list for PBXProject "TLChart" */ = { 370 | isa = XCConfigurationList; 371 | buildConfigurations = ( 372 | CE16B199228131EC00721F5F /* Debug */, 373 | CE16B19A228131EC00721F5F /* Release */, 374 | ); 375 | defaultConfigurationIsVisible = 0; 376 | defaultConfigurationName = Release; 377 | }; 378 | CE16B19B228131EC00721F5F /* Build configuration list for PBXNativeTarget "TLChart" */ = { 379 | isa = XCConfigurationList; 380 | buildConfigurations = ( 381 | CE16B19C228131EC00721F5F /* Debug */, 382 | CE16B19D228131EC00721F5F /* Release */, 383 | ); 384 | defaultConfigurationIsVisible = 0; 385 | defaultConfigurationName = Release; 386 | }; 387 | /* End XCConfigurationList section */ 388 | }; 389 | rootObject = CE16B17D228131EA00721F5F /* Project object */; 390 | } 391 | -------------------------------------------------------------------------------- /TLChart.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TLChart.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TLChart.xcodeproj/project.xcworkspace/xcuserdata/hello.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepiec/TLChart/a6f55c23f53907ea4bb0d58a687957399ad84115/TLChart.xcodeproj/project.xcworkspace/xcuserdata/hello.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TLChart.xcodeproj/xcuserdata/hello.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TLChart.xcodeproj/xcuserdata/hello.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TLChart.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /TLChart/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepiec/TLChart/a6f55c23f53907ea4bb0d58a687957399ad84115/TLChart/.DS_Store -------------------------------------------------------------------------------- /TLChart/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. 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 | -------------------------------------------------------------------------------- /TLChart/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 22 | self.window.backgroundColor = [UIColor whiteColor]; 23 | 24 | UINavigationController *Nav = [[UINavigationController alloc] initWithRootViewController:[ViewController new]]; 25 | self.window.rootViewController = Nav; 26 | [self.window makeKeyAndVisible]; 27 | return YES; 28 | } 29 | 30 | 31 | - (void)applicationWillResignActive:(UIApplication *)application { 32 | // 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. 33 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 34 | } 35 | 36 | 37 | - (void)applicationDidEnterBackground:(UIApplication *)application { 38 | // 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. 39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 40 | } 41 | 42 | 43 | - (void)applicationWillEnterForeground:(UIApplication *)application { 44 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 45 | } 46 | 47 | 48 | - (void)applicationDidBecomeActive:(UIApplication *)application { 49 | // 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. 50 | } 51 | 52 | 53 | - (void)applicationWillTerminate:(UIApplication *)application { 54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 55 | } 56 | 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /TLChart/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /TLChart/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TLChart/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TLChart/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /TLChart/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 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 | -------------------------------------------------------------------------------- /TLChart/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | #define WS(weakSelf) __weak __typeof(&*self)weakSelf = self; 13 | #define SS(strongSelf) __strong __typeof(&*self)strongSelf = weakSelf; 14 | 15 | #define TLDeviceWidth [UIScreen mainScreen].bounds.size.width 16 | #define TLDeviceHeight [UIScreen mainScreen].bounds.size.height 17 | 18 | #define NavBarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?88:64) 19 | #define EXStatusHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?24:0) 20 | #define TabBarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?83:49) 21 | #define EXTabHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?34:0) 22 | 23 | #endif /* PrefixHeader_pch */ 24 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartDoubleHistogramView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartDoubleHistogramView.h 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/1. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface TLChartDoubleHistogramView : UIView 14 | 15 | @property (nonatomic, assign) CGFloat corner;//柱状图圆角 16 | @property (nonatomic, assign) CGFloat verTitleWidth;//左边title宽度 17 | @property (nonatomic, assign) CGFloat horTitleHeight;//下边title高度 18 | 19 | @property (nonatomic, strong) NSArray *verTitleArr;//左边title数据 20 | @property (nonatomic, strong) NSArray *horTitleArr;//下边title数据 21 | 22 | @property (nonatomic, strong) NSArray *data0Arr;//柱状图0设定宽度的数据-可以转化floatValue 23 | @property (nonatomic, strong) NSArray *data1Arr;//柱状图1设定宽度的数据-可以转化floatValue 24 | 25 | @property (nonatomic, strong) NSArray *dataTitle0Arr;//柱状图0上面显示的数据 26 | @property (nonatomic, strong) NSArray *dataColor0Arr;//柱状图0的颜色 27 | 28 | @property (nonatomic, strong) NSArray *dataTitle1Arr;//柱状图1上面显示的数据 29 | @property (nonatomic, strong) NSArray *dataColor1Arr;//柱状图1的颜色 30 | 31 | @property (nonatomic, strong) UIColor *titleColor;//title颜色 32 | @property (nonatomic, strong) UIColor *contentColor;//柱状图内容颜色 33 | 34 | @property (nonatomic, assign) CGFloat verTitleFont;//左边title字号 35 | @property (nonatomic, assign) CGFloat horTitleFont;//下边title字号 36 | @property (nonatomic, assign) CGFloat contentFont;//柱状图内容字号 37 | 38 | @property (nonatomic, strong) UIColor *lineColor;//line的颜色 39 | @property (nonatomic, assign) CGFloat lineWidth;//line的粗细 40 | @property (nonatomic, assign) CGFloat extLineWidth;//突出line的长短 41 | 42 | 43 | @property (nonatomic,copy) void(^ clickBlock)(NSInteger secIndex ,NSInteger rowIndex); 44 | - (void)reloadData; 45 | 46 | @end 47 | 48 | NS_ASSUME_NONNULL_END 49 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartDoubleHistogramView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartDoubleHistogramView.m 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/1. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "TLChartDoubleHistogramView.h" 10 | 11 | @interface TLChartDoubleHistogramView() 12 | 13 | 14 | @property (nonatomic,weak) CALayer * contentLayer; 15 | @property (nonatomic,assign)CGFloat allLineWidth; 16 | 17 | @end 18 | @implementation TLChartDoubleHistogramView 19 | 20 | -(instancetype)initWithFrame:(CGRect)frame{ 21 | 22 | if (self = [super initWithFrame:frame]) { 23 | 24 | _corner = 4; 25 | _verTitleWidth = 80; 26 | _horTitleHeight = 50; 27 | 28 | _titleColor = [UIColor blackColor]; 29 | _contentColor = [UIColor blackColor]; 30 | _verTitleFont = 15; 31 | _horTitleFont = 15; 32 | _contentFont = 12; 33 | _lineColor = [UIColor blackColor]; 34 | _lineWidth = 1; 35 | _extLineWidth = 3; 36 | 37 | } 38 | return self; 39 | } 40 | - (void)choseItemAction:(UITapGestureRecognizer *)tapGesture{ 41 | 42 | CGPoint tapPoint = [tapGesture locationInView:self]; 43 | CGFloat cellHeight = (CGRectGetHeight(self.frame) -_horTitleHeight)/self.verTitleArr.count; 44 | 45 | for (int i =0; i = _verTitleWidth && tapPoint.x <= _verTitleWidth +itemtWidth0) && 51 | (tapPoint.y >= cellHeight/9 +cellHeight *i && tapPoint.y <= cellHeight *4/9 +cellHeight *i)) { 52 | 53 | if (self.clickBlock) { 54 | self.clickBlock(0, i); 55 | } 56 | return; 57 | } 58 | if ((tapPoint.x >= _verTitleWidth && tapPoint.x <= _verTitleWidth +itemtWidth1) && 59 | (tapPoint.y >= cellHeight *5/9 +cellHeight *i && tapPoint.y <= cellHeight *8/9 +cellHeight *i)) { 60 | 61 | if (self.clickBlock) { 62 | self.clickBlock(1, i); 63 | } 64 | return; 65 | } 66 | 67 | 68 | } 69 | 70 | } 71 | - (void)layoutSubviews{ 72 | 73 | [super layoutSubviews]; 74 | [self.layer addSublayer:self.contentLayer]; 75 | 76 | UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(choseItemAction:)]; 77 | [self addGestureRecognizer:tap]; 78 | 79 | [self tl_layoutContent]; 80 | 81 | } 82 | - (void)reloadData{ 83 | self.layer.contents = nil; 84 | [self tl_layoutContent]; 85 | } 86 | - (CALayer *)contentLayer{ 87 | if (_contentLayer == nil) { 88 | CALayer * contentLayer = [CALayer layer]; 89 | contentLayer.backgroundColor = [UIColor clearColor].CGColor; 90 | contentLayer.frame = self.bounds; 91 | _contentLayer = contentLayer; 92 | } 93 | return _contentLayer; 94 | } 95 | - (void)tl_layoutContent{ 96 | 97 | //文字居中显示在画布上 98 | NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 99 | paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;// 这个属性是能够画字符的时候换行 100 | paragraphStyle.alignment = NSTextAlignmentCenter; 101 | 102 | 103 | UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale); 104 | CGContextRef context = UIGraphicsGetCurrentContext(); 105 | CGContextSetLineWidth(context, _lineWidth); 106 | 107 | 108 | [_lineColor setStroke]; 109 | // 画竖线 110 | CGContextSetLineWidth(context, _lineWidth); 111 | CGContextMoveToPoint(context, _verTitleWidth, 0); 112 | CGContextAddLineToPoint(context, _verTitleWidth, CGRectGetHeight(self.frame) -_horTitleHeight); 113 | CGContextStrokePath(context); 114 | 115 | 116 | //画横线 117 | CGSize lastStrSize = [[self.horTitleArr lastObject] sizeWithAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:_horTitleFont],NSForegroundColorAttributeName:_titleColor,NSParagraphStyleAttributeName:paragraphStyle}]; 118 | _allLineWidth = CGRectGetWidth(self.frame) -_verTitleWidth -lastStrSize.width/2; 119 | 120 | CGContextSetLineWidth(context, _lineWidth); 121 | CGContextMoveToPoint(context, _verTitleWidth, CGRectGetHeight(self.frame) -_horTitleHeight); 122 | CGContextAddLineToPoint(context, _verTitleWidth +_allLineWidth, CGRectGetHeight(self.frame) -_horTitleHeight); 123 | CGContextStrokePath(context); 124 | 125 | //画额外的横线 126 | CGFloat cellHeight = (CGRectGetHeight(self.frame) -_horTitleHeight)/self.verTitleArr.count; 127 | for (int i = 0; i < self.verTitleArr.count +1; i ++) { 128 | 129 | CGContextSetLineWidth(context, _lineWidth); 130 | CGContextMoveToPoint(context, _verTitleWidth -_extLineWidth, cellHeight *i); 131 | CGContextAddLineToPoint(context, _verTitleWidth, cellHeight *i); 132 | CGContextStrokePath(context); 133 | } 134 | //画额外的竖线 135 | CGFloat cellWidth = _allLineWidth/(self.horTitleArr.count -1); 136 | for (int i = 0; i < self.horTitleArr.count; i ++) { 137 | 138 | CGContextSetLineWidth(context, _lineWidth); 139 | CGContextMoveToPoint(context, _verTitleWidth +cellWidth *i, CGRectGetHeight(self.frame) -_horTitleHeight); 140 | CGContextAddLineToPoint(context, _verTitleWidth +cellWidth *i, CGRectGetHeight(self.frame) -_horTitleHeight +_extLineWidth); 141 | CGContextStrokePath(context); 142 | } 143 | 144 | //画竖向的标题 145 | CGFloat allHorExtHeight = 0; 146 | for (int i =0; i 0) { 180 | content0Color = self.dataColor0Arr[i]; 181 | } 182 | [content0Color setFill]; 183 | 184 | CGFloat itemWidth0 = _allLineWidth *[self.data0Arr[i] floatValue]; 185 | 186 | CGContextMoveToPoint(context, _verTitleWidth, cellHeight/9 +cellHeight *i); 187 | 188 | CGContextAddArcToPoint(context, _verTitleWidth +itemWidth0, cellHeight/9 +cellHeight *i, _verTitleWidth +itemWidth0, cellHeight/9 +cellHeight *i +_corner *2, _corner); 189 | CGContextAddArcToPoint(context, _verTitleWidth +itemWidth0, cellHeight *4/9 +cellHeight *i, _verTitleWidth +itemWidth0 -_corner *2, cellHeight *4/9 +cellHeight *i, _corner); 190 | 191 | // CGContextAddLineToPoint(context, _verTitleWidth +itemWidth0, cellHeight/9 +cellHeight *i); 192 | // CGContextAddLineToPoint(context, _verTitleWidth +itemWidth0,cellHeight *4/9 +cellHeight *i); 193 | CGContextAddLineToPoint(context,_verTitleWidth, cellHeight *4/9 +cellHeight *i); 194 | CGContextFillPath(context); 195 | 196 | //画第一种柱状图里面的文字 197 | NSDictionary *attributes0 = @{ NSFontAttributeName:[UIFont systemFontOfSize:_contentFont],NSForegroundColorAttributeName:_contentColor,NSParagraphStyleAttributeName:paragraphStyle}; 198 | 199 | NSString *title0 = self.dataTitle0Arr[i]; 200 | CGSize strSize0 = [title0 sizeWithAttributes:attributes0]; 201 | [title0 drawInRect:CGRectMake(_verTitleWidth, cellHeight/9 +cellHeight *i +(cellHeight/3 -strSize0.height)/2, itemWidth0, strSize0.height) withAttributes:attributes0]; 202 | 203 | 204 | //画第二种柱状图 205 | UIColor *content1Color = [UIColor redColor]; 206 | if (self.dataColor1Arr.count >0) { 207 | content1Color = self.dataColor1Arr[i]; 208 | } 209 | [content1Color setFill]; 210 | 211 | CGFloat itemWidth1 = _allLineWidth *[self.data1Arr[i] floatValue]; 212 | 213 | CGContextMoveToPoint(context, _verTitleWidth, cellHeight *5/9 +cellHeight *i); 214 | 215 | CGContextAddArcToPoint(context, _verTitleWidth +itemWidth1, cellHeight *5/9 +cellHeight *i, _verTitleWidth +itemWidth1, cellHeight *5/9 +cellHeight *i +_corner *2, _corner); 216 | CGContextAddArcToPoint(context, _verTitleWidth +itemWidth1, cellHeight *8/9 +cellHeight *i, _verTitleWidth +itemWidth1 -_corner *2, cellHeight *8/9 +cellHeight *i, _corner); 217 | 218 | // CGContextAddLineToPoint(context, _verTitleWidth +itemWidth1, cellHeight *5/9 +cellHeight *i); 219 | // CGContextAddLineToPoint(context, _verTitleWidth +itemWidth1,cellHeight *8/9 +cellHeight *i); 220 | CGContextAddLineToPoint(context,_verTitleWidth, cellHeight *8/9 +cellHeight *i); 221 | CGContextFillPath(context); 222 | 223 | //画第二种柱状图里面的文字 224 | NSDictionary *attributes1 = @{ NSFontAttributeName:[UIFont systemFontOfSize:_contentFont],NSForegroundColorAttributeName:_contentColor,NSParagraphStyleAttributeName:paragraphStyle}; 225 | 226 | NSString *title1 = self.dataTitle1Arr[i]; 227 | CGSize strSize1 = [title1 sizeWithAttributes:attributes1]; 228 | [title1 drawInRect:CGRectMake(_verTitleWidth, cellHeight *5/9 +cellHeight *i +(cellHeight/3 -strSize1.height)/2, itemWidth1, strSize1.height) withAttributes:attributes1]; 229 | } 230 | 231 | 232 | 233 | UIImage * currentImage = UIGraphicsGetImageFromCurrentImageContext(); 234 | UIGraphicsEndImageContext(); 235 | self.contentLayer.contents = (__bridge id _Nullable)(currentImage.CGImage); 236 | 237 | } 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartRateView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartRateView.h 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/3. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | #define RateViewWidth 300 9 | #define RateViewHeight RateViewWidth/2 +15 *2 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface TLChartRateView : UIView 16 | 17 | @property (nonatomic, assign) CGFloat needleRadius;//针头的半径 18 | @property (nonatomic, strong) UIColor *needleColor;//针的颜色 19 | 20 | @property (nonatomic, assign) CGFloat lineWidth;//底部虚线宽度 21 | @property (nonatomic, strong) UIColor *lineColor;//底部虚线颜色 22 | 23 | @property (nonatomic, copy ) NSString *title;//title数据 24 | @property (nonatomic, assign) CGFloat titleFont;//title字号 25 | @property (nonatomic, strong) UIColor *titleColor;//title字色 26 | 27 | @property (nonatomic, assign) CGFloat arcWidth;//环形宽度 28 | @property (nonatomic, copy ) NSString *arcData;//环形比例数据 29 | @property (nonatomic, strong) UIColor *arcColor0;//环形色 30 | @property (nonatomic, strong) UIColor *arcColor1;//环形默认色 31 | 32 | @property (nonatomic, strong) NSArray *defaultTextArr;//环形里面数据 33 | @property (nonatomic, assign) CGFloat defaultTextFont;//环形里面字号 34 | @property (nonatomic, strong) UIColor *defaultTextColor;//环形里面字色 35 | 36 | - (void)reloadData; 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartRateView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartRateView.m 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/3. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "TLChartRateView.h" 10 | 11 | @interface TLChartRateView() 12 | 13 | @property (nonatomic,strong) CALayer * contentLayer; 14 | 15 | @end 16 | 17 | @implementation TLChartRateView 18 | 19 | -(instancetype)initWithFrame:(CGRect)frame{ 20 | 21 | if (self = [super initWithFrame:frame]) { 22 | 23 | 24 | _needleRadius = 5; 25 | _needleColor = [UIColor blackColor]; 26 | 27 | _lineWidth = 1; 28 | _lineColor = [UIColor blackColor]; 29 | 30 | _title = @"饼图/速率图"; 31 | _titleFont = 15; 32 | _titleColor = [UIColor redColor]; 33 | 34 | _arcWidth = 15; 35 | _arcData = @"0"; 36 | _arcColor0 = [UIColor colorWithRed:82.0 / 255.0 green:116.0 / 255.0 blue:188.0 / 255.0 alpha:1.0f]; 37 | _arcColor1 = [UIColor grayColor]; 38 | 39 | _defaultTextArr = @[@"30",@"70"]; 40 | _defaultTextFont = 12; 41 | _defaultTextColor = [UIColor grayColor]; 42 | 43 | 44 | } 45 | return self; 46 | } 47 | - (void)layoutSubviews{ 48 | 49 | [super layoutSubviews]; 50 | [self.layer addSublayer:self.contentLayer]; 51 | 52 | [self tl_layoutContent]; 53 | 54 | } 55 | - (void)reloadData{ 56 | 57 | self.layer.contents = nil; 58 | [self tl_layoutContent]; 59 | // [self layoutSubviews]; 60 | 61 | } 62 | 63 | - (CALayer *)contentLayer{ 64 | if (_contentLayer == nil) { 65 | 66 | _contentLayer = [CALayer layer]; 67 | _contentLayer.backgroundColor = [UIColor clearColor].CGColor; 68 | _contentLayer.frame = self.bounds; 69 | 70 | } 71 | return _contentLayer; 72 | } 73 | - (void)tl_layoutContent{ 74 | 75 | UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale); 76 | CGContextRef context = UIGraphicsGetCurrentContext(); 77 | 78 | //文字居中显示在画布上 79 | NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 80 | paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;// 这个属性是能够画字符的时候换行 81 | paragraphStyle.alignment = NSTextAlignmentCenter; 82 | 83 | //画title 84 | NSDictionary *attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:_titleFont],NSForegroundColorAttributeName:_titleColor,NSParagraphStyleAttributeName:paragraphStyle}; 85 | [_title drawInRect:CGRectMake(0, 0, CGRectGetWidth(self.frame), _titleFont) withAttributes:attributes]; 86 | 87 | 88 | //画半圆 89 | CGContextSetLineWidth(context, _arcWidth); 90 | CGContextSetLineCap(context, kCGLineCapButt);//线条起点终点样式 91 | 92 | // 计算空白半径 93 | CGFloat radius = CGRectGetWidth(self.frame)/2 - _arcWidth/2; 94 | double angle = -M_PI -(-M_PI *[_arcData floatValue]); 95 | /* 96 | CGFloat x 圆心x坐标 97 | CGFloat y 圆形y坐标 98 | CGFloat radius 圆半径 99 | CGFloat startAngle 起始弧度 100 | CGFloat endAngle 结束弧度 101 | int clockwise 绘制方向,0 顺时针,1 逆时针 102 | */ 103 | //第一段 104 | [_arcColor0 setStroke]; 105 | CGContextAddArc(context, CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame), radius, -M_PI, angle, 0); 106 | CGContextDrawPath(context, kCGPathStroke); 107 | //第二段 108 | [_arcColor1 setStroke]; 109 | CGContextAddArc(context, CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame), radius, angle, 0, 0); 110 | CGContextDrawPath(context, kCGPathStroke); 111 | 112 | //虚线 113 | [_lineColor setStroke]; 114 | CGContextSetLineWidth(context, _lineWidth); 115 | CGFloat lengths[] = {3,2};//线长,空白长 116 | CGContextSetLineDash(context, 0, lengths, 2);//起始长度-lengths-lengths数组长度 117 | //横 118 | CGContextMoveToPoint(context, 0, CGRectGetHeight(self.frame) -_lineWidth); 119 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) -_lineWidth); 120 | CGContextStrokePath(context); 121 | //竖 122 | CGContextMoveToPoint(context, CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame) -CGRectGetWidth(self.frame)/2); 123 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame)); 124 | CGContextStrokePath(context); 125 | 126 | //content文字 127 | for (int i =0; i <_defaultTextArr.count; i ++) { 128 | 129 | NSString *contentStr = _defaultTextArr[i]; 130 | CGRect rect; 131 | if (0 == i) { 132 | paragraphStyle.alignment = NSTextAlignmentLeft; 133 | rect = CGRectMake(_arcWidth +5, CGRectGetHeight(self.frame) -(_defaultTextFont +2), CGRectGetWidth(self.frame)/2 -(_arcWidth +5), _defaultTextFont); 134 | }else{ 135 | paragraphStyle.alignment = NSTextAlignmentRight; 136 | rect = CGRectMake(CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame) -(_defaultTextFont +2), CGRectGetWidth(self.frame)/2 -(_arcWidth +5), _defaultTextFont); 137 | } 138 | 139 | //画content 140 | NSDictionary *attribute = @{ NSFontAttributeName:[UIFont systemFontOfSize:_defaultTextFont],NSForegroundColorAttributeName:_defaultTextColor,NSParagraphStyleAttributeName:paragraphStyle}; 141 | [contentStr drawInRect:rect withAttributes:attribute]; 142 | 143 | } 144 | 145 | //针 146 | [_needleColor setFill]; 147 | //针头point 148 | CGPoint point0 = [self calcCircleCoordinateWithCenter:CGPointMake(CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame)) andWithAngle:angle andWithRadius:CGRectGetWidth(self.frame)/2]; 149 | 150 | //针尾左边弧度 151 | double angle1 = angle -M_PI_2; 152 | //针尾右边弧度 153 | double angle2 = angle +M_PI_2; 154 | 155 | CGContextAddArc(context, CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame) -_needleRadius, _needleRadius, angle1, angle2, 1); 156 | CGContextAddLineToPoint(context, point0.x, point0.y); 157 | CGContextFillPath(context); 158 | 159 | UIImage * currentImage = UIGraphicsGetImageFromCurrentImageContext(); 160 | UIGraphicsEndImageContext(); 161 | self.contentLayer.contents = (__bridge id _Nullable)(currentImage.CGImage); 162 | } 163 | #pragma mark 计算圆圈上点在IOS系统中的坐标 164 | /* 165 | center中心点坐标 166 | angle是角度,如果是6个点 应分别传入 60 120 180 240 300 360 167 | radius半径 168 | */ 169 | - (CGPoint)calcCircleCoordinateWithCenter:(CGPoint)center andWithAngle:(CGFloat)angle andWithRadius: (CGFloat) radius{ 170 | 171 | CGFloat x2 = radius*cosf(angle); 172 | CGFloat y2 = radius*sinf(angle); 173 | return CGPointMake(center.x+x2, center.y+y2); 174 | } 175 | 176 | @end 177 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartRateView1.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartRateView1.h 3 | // test 4 | // 5 | // Created by hello on 2019/5/6. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | #define RateViewWidth 300 9 | #define RateViewHeight RateViewWidth/2 +15 *2 10 | #define durationTime 1 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface TLChartRateView1 : UIView 17 | 18 | @property (nonatomic, assign) CGFloat needleRadius;//针头的半径 19 | @property (nonatomic, strong) UIColor *needleColor;//针的颜色 20 | 21 | @property (nonatomic, assign) CGFloat lineWidth;//底部虚线宽度 22 | @property (nonatomic, strong) UIColor *lineColor;//底部虚线颜色 23 | 24 | @property (nonatomic, copy ) NSString *title;//title数据 25 | @property (nonatomic, assign) CGFloat titleFont;//title字号 26 | @property (nonatomic, strong) UIColor *titleColor;//title字色 27 | 28 | @property (nonatomic, assign) CGFloat arcWidth;//环形宽度 29 | @property (nonatomic, assign) CGFloat arcData;//环形比例数据 30 | @property (nonatomic, strong) UIColor *arcColor0;//环形色 31 | @property (nonatomic, strong) UIColor *arcColor1;//环形默认色 32 | 33 | @property (nonatomic, strong) NSArray *defaultTextArr;//环形里面数据 34 | @property (nonatomic, assign) CGFloat defaultTextFont;//环形里面字号 35 | @property (nonatomic, strong) UIColor *defaultTextColor;//环形里面字色 36 | 37 | - (void)reloadData; 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartRateView1.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartRateView1.m 3 | // test 4 | // 5 | // Created by hello on 2019/5/6. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "TLChartRateView1.h" 10 | 11 | @interface TLChartRateView1() 12 | 13 | @property (nonatomic,weak) CALayer *contentLayer; 14 | @property (nonatomic,weak) CAShapeLayer *needleLayer; 15 | @property (nonatomic,strong)CABasicAnimation *needleAnimation; 16 | @property (nonatomic,assign)double needleAngle; 17 | 18 | @property (nonatomic,weak)CAShapeLayer *animationLayer; //动画效果mask 19 | @property (nonatomic,strong)CABasicAnimation *animation; 20 | 21 | @end 22 | 23 | @implementation TLChartRateView1 24 | 25 | - (CABasicAnimation *)needleAnimation{ 26 | if (!_needleAnimation) { 27 | _needleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 28 | 29 | _needleAnimation.fromValue = @(-M_PI_2); 30 | _needleAnimation.fillMode = kCAFillModeForwards; 31 | _needleAnimation.removedOnCompletion = NO; 32 | _needleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 33 | } 34 | if (_needleAnimation) { 35 | _needleAnimation.duration = durationTime *_arcData; 36 | _needleAnimation.toValue = @(M_PI_2 +self.needleAngle); 37 | 38 | } 39 | return _needleAnimation; 40 | } 41 | 42 | - (CABasicAnimation *)animation{ 43 | if (!_animation) { 44 | _animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 45 | _animation.duration = durationTime; 46 | _animation.fromValue = @(0); 47 | _animation.toValue = @(1); 48 | _animation.removedOnCompletion = NO; 49 | _animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];; 50 | } 51 | return _animation; 52 | } 53 | - (CAShapeLayer *)animationLayer{ 54 | if (!_animationLayer) { 55 | 56 | UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(RateViewWidth/2, RateViewHeight) radius:RateViewWidth/2 startAngle:-M_PI_2 *2 endAngle:0 clockwise:YES]; 57 | CAShapeLayer *layer = [CAShapeLayer layer]; 58 | layer.path = path.CGPath; 59 | layer.fillColor = [UIColor clearColor].CGColor; 60 | layer.strokeColor = [UIColor blackColor].CGColor; 61 | layer.lineWidth = RateViewWidth; 62 | _animationLayer = layer; 63 | } 64 | return _animationLayer; 65 | } 66 | - (void)addAnimation{ 67 | 68 | self.contentLayer.mask = self.animationLayer; 69 | [self.animationLayer removeAnimationForKey:@"starAnimation"]; 70 | [self.animationLayer addAnimation:self.animation forKey:@"starAnimation"]; 71 | 72 | [self.needleLayer removeAnimationForKey:@"rotate-layer"]; 73 | [self.needleLayer addAnimation:self.needleAnimation forKey:@"rotate-layer"]; 74 | } 75 | 76 | -(instancetype)initWithFrame:(CGRect)frame{ 77 | 78 | if (self = [super initWithFrame:frame]) { 79 | 80 | 81 | _needleRadius = 5; 82 | _needleColor = [UIColor blackColor]; 83 | 84 | _lineWidth = 1; 85 | _lineColor = [UIColor blackColor]; 86 | 87 | _title = @"饼图/速率图"; 88 | _titleFont = 15; 89 | _titleColor = [UIColor redColor]; 90 | 91 | _arcWidth = 15; 92 | _arcData = 0.3; 93 | _arcColor0 = [UIColor colorWithRed:82.0 / 255.0 green:116.0 / 255.0 blue:188.0 / 255.0 alpha:1.0f]; 94 | _arcColor1 = [UIColor grayColor]; 95 | 96 | _defaultTextArr = @[@"30",@"70"]; 97 | _defaultTextFont = 12; 98 | _defaultTextColor = [UIColor grayColor]; 99 | 100 | 101 | } 102 | return self; 103 | } 104 | - (void)layoutSubviews{ 105 | 106 | [super layoutSubviews]; 107 | [self.layer addSublayer:self.contentLayer]; 108 | 109 | [self tl_layoutContent]; 110 | [self addAnimation]; 111 | 112 | } 113 | - (void)reloadData{ 114 | 115 | [self.contentLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; 116 | [self.contentLayer removeFromSuperlayer]; 117 | self.contentLayer = nil; 118 | 119 | [self.needleLayer removeFromSuperlayer]; 120 | self.needleLayer = nil; 121 | } 122 | 123 | - (CALayer *)contentLayer{ 124 | if (_contentLayer == nil) { 125 | 126 | CALayer *contentLayer = [CALayer layer]; 127 | contentLayer.backgroundColor = [UIColor clearColor].CGColor; 128 | contentLayer.frame = self.bounds; 129 | _contentLayer = contentLayer; 130 | 131 | } 132 | return _contentLayer; 133 | } 134 | - (void)tl_layoutContent{ 135 | 136 | 137 | NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 138 | paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;// 这个属性是能够画字符的时候换行 139 | paragraphStyle.alignment = NSTextAlignmentCenter; 140 | 141 | NSDictionary *attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:_titleFont],NSForegroundColorAttributeName:_titleColor,NSParagraphStyleAttributeName:paragraphStyle}; 142 | 143 | NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:_title attributes:attributes]; 144 | 145 | 146 | CATextLayer *titleLayer = [[CATextLayer alloc] init]; 147 | titleLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), 15); 148 | titleLayer.alignmentMode = kCAAlignmentCenter; 149 | titleLayer.string = attributedStr; 150 | titleLayer.contentsScale = [UIScreen mainScreen].scale; 151 | [_contentLayer addSublayer:titleLayer]; 152 | 153 | 154 | CGPoint arcCenter = CGPointMake(CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame)); 155 | CGFloat arcRadius = CGRectGetWidth(self.frame)/2; 156 | double angle = -M_PI -(-M_PI *_arcData); 157 | self.needleAngle = angle; 158 | 159 | UIBezierPath *arcPath0 = [UIBezierPath bezierPathWithArcCenter:arcCenter 160 | radius:arcRadius 161 | startAngle:-M_PI 162 | endAngle:angle clockwise:YES]; 163 | [arcPath0 addLineToPoint:arcCenter]; 164 | CAShapeLayer *arcLayer0 = [CAShapeLayer layer]; 165 | arcLayer0.path = arcPath0.CGPath; 166 | arcLayer0.fillColor = _arcColor0.CGColor; 167 | [_contentLayer addSublayer:arcLayer0]; 168 | 169 | UIBezierPath *arcPath1 = [UIBezierPath bezierPathWithArcCenter:arcCenter 170 | radius:arcRadius 171 | startAngle:angle 172 | endAngle:0 clockwise:YES]; 173 | [arcPath1 addLineToPoint:arcCenter]; 174 | CAShapeLayer *arcLayer1 = [CAShapeLayer layer]; 175 | arcLayer1.path = arcPath1.CGPath; 176 | arcLayer1.fillColor = _arcColor1.CGColor; 177 | [_contentLayer addSublayer:arcLayer1]; 178 | 179 | // 计算空白半径 180 | CGFloat whiteRadius = CGRectGetWidth(self.frame)/2 - _arcWidth; 181 | UIBezierPath *whiteArcPath = [UIBezierPath bezierPathWithArcCenter:arcCenter 182 | radius:whiteRadius 183 | startAngle:-M_PI 184 | endAngle:0 clockwise:YES]; 185 | [whiteArcPath addLineToPoint:arcCenter]; 186 | CAShapeLayer *whiteArcLayer = [CAShapeLayer layer]; 187 | whiteArcLayer.path = whiteArcPath.CGPath; 188 | whiteArcLayer.fillColor = [UIColor whiteColor].CGColor; 189 | [_contentLayer addSublayer:whiteArcLayer]; 190 | 191 | 192 | CGRect horLineFrame = CGRectMake(0, CGRectGetHeight(self.frame) -_lineWidth, CGRectGetWidth(self.frame), _lineWidth); 193 | CAShapeLayer *horLine = [CAShapeLayer layer]; 194 | horLine.frame = horLineFrame; 195 | horLine.strokeColor = _lineColor.CGColor; 196 | horLine.fillColor = [UIColor clearColor].CGColor; 197 | horLine.lineWidth = _lineWidth;//虚线伸出去的宽度 198 | horLine.lineDashPattern = @[@3,@2];//虚线高度 & 两虚线间隔高度 199 | 200 | CGMutablePathRef horPath = CGPathCreateMutable(); 201 | CGPathMoveToPoint(horPath, NULL, 0, 0); 202 | CGPathAddLineToPoint(horPath, NULL, CGRectGetWidth(self.frame),0); 203 | horLine.path = horPath; 204 | [_contentLayer addSublayer:horLine]; 205 | 206 | 207 | CGRect verLineFrame = CGRectMake((CGRectGetWidth(self.frame) -_lineWidth)/2, CGRectGetHeight(self.frame) -CGRectGetWidth(self.frame)/2, _lineWidth, CGRectGetWidth(self.frame)/2); 208 | CAShapeLayer *verLine = [CAShapeLayer layer]; 209 | verLine.frame = verLineFrame; 210 | verLine.strokeColor = _lineColor.CGColor; 211 | verLine.fillColor = [UIColor clearColor].CGColor; 212 | verLine.lineWidth = _lineWidth;//虚线伸出去的宽度 213 | verLine.lineDashPattern = @[@3,@2];//虚线高度 & 两虚线间隔高度 214 | 215 | CGMutablePathRef verPath = CGPathCreateMutable(); 216 | CGPathMoveToPoint(verPath, NULL, 0, 0); 217 | CGPathAddLineToPoint(verPath, NULL, 0,CGRectGetWidth(self.frame)/2); 218 | verLine.path = verPath; 219 | [_contentLayer addSublayer:verLine]; 220 | 221 | //content文字 222 | for (int i =0; i <_defaultTextArr.count; i ++) { 223 | 224 | CATextLayer *contentLayer = [[CATextLayer alloc] init]; 225 | if (0 == i) { 226 | contentLayer.frame = CGRectMake(_arcWidth +5, CGRectGetHeight(self.frame) -(_defaultTextFont +2), CGRectGetWidth(self.frame)/2 -(_arcWidth +5), _defaultTextFont); 227 | contentLayer.alignmentMode = kCAAlignmentLeft; 228 | }else{ 229 | contentLayer.frame = CGRectMake(CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame) -(_defaultTextFont +2), CGRectGetWidth(self.frame)/2 -(_arcWidth +5), _defaultTextFont); 230 | contentLayer.alignmentMode = kCAAlignmentRight; 231 | } 232 | 233 | contentLayer.string = _defaultTextArr[i]; 234 | contentLayer.fontSize = _defaultTextFont; 235 | contentLayer.foregroundColor = _defaultTextColor.CGColor; 236 | contentLayer.contentsScale = [UIScreen mainScreen].scale; 237 | [_contentLayer addSublayer:contentLayer]; 238 | 239 | } 240 | 241 | 242 | CGRect needleRect = CGRectMake(RateViewWidth/2 -_needleRadius, RateViewHeight -RateViewWidth/2, _needleRadius *2, RateViewWidth/2); 243 | double newAngle = -M_PI_2; 244 | //针尾左边弧度 245 | double needleAngle0 = newAngle -M_PI_2; 246 | //针尾右边弧度 247 | double needleAngle1 = newAngle +M_PI_2; 248 | 249 | //圆心坐标 250 | CGPoint needleCenter = CGPointMake(CGRectGetWidth(needleRect)/2, CGRectGetHeight(needleRect));//-_needleRadius 251 | 252 | //针头point 253 | CGPoint needlePoint = CGPointMake(_needleRadius, 0); 254 | UIBezierPath *needlePath = [UIBezierPath bezierPathWithArcCenter:needleCenter 255 | radius:_needleRadius 256 | startAngle:needleAngle0 257 | endAngle:needleAngle1 clockwise:NO]; 258 | [needlePath addLineToPoint:needlePoint]; 259 | CAShapeLayer *needleLayer = [CAShapeLayer layer]; 260 | needleLayer.frame = needleRect; 261 | needleLayer.path = needlePath.CGPath; 262 | needleLayer.fillColor = _needleColor.CGColor; 263 | needleLayer.position = CGPointMake(needleLayer.position.x, needleLayer.position.y +CGRectGetHeight(needleRect)/2);// -_needleRadius 264 | needleLayer.anchorPoint = CGPointMake(0.5, 0.5 +(CGRectGetHeight(needleRect)/2)/(RateViewWidth/2));//-_needleRadius 265 | 266 | [self.layer addSublayer:needleLayer]; 267 | _needleLayer = needleLayer; 268 | 269 | } 270 | 271 | @end 272 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartSingleHistogramView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartSingleHistogramView.h 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/1. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface TLChartSingleHistogramView : UIView 14 | 15 | @property (nonatomic, assign) CGFloat corner;//柱状图圆角 16 | @property (nonatomic, assign) CGFloat verTitleWidth;//左边title宽度 17 | @property (nonatomic, assign) CGFloat horTitleHeight;//下边title高度 18 | 19 | @property (nonatomic, strong) NSArray *verTitleArr;//左边title数据 20 | @property (nonatomic, strong) NSArray *horTitleArr;//下边title数据 21 | @property (nonatomic, strong) NSArray *dataArr;//柱状图设定宽度的数据-可以转化floatValue 22 | @property (nonatomic, strong) NSArray *dataTitleArr;//柱状图上面显示的数据 23 | @property (nonatomic, strong) NSArray *dataColorArr;//柱状图的颜色 24 | 25 | @property (nonatomic, strong) UIColor *titleColor;//title颜色 26 | @property (nonatomic, strong) UIColor *contentColor;//柱状图内容颜色 27 | 28 | @property (nonatomic, assign) CGFloat verTitleFont;//左边title字号 29 | @property (nonatomic, assign) CGFloat horTitleFont;//下边title字号 30 | @property (nonatomic, assign) CGFloat contentFont;//柱状图内容字号 31 | 32 | @property (nonatomic, strong) UIColor *lineColor;//line的颜色 33 | @property (nonatomic, assign) CGFloat lineWidth;//line的粗细 34 | @property (nonatomic, assign) CGFloat extLineWidth;//突出line的长短 35 | 36 | @property (nonatomic,copy) void(^ clickBlock)(NSInteger index); 37 | - (void)reloadData; 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartSingleHistogramView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartSingleHistogramView.m 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/1. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "TLChartSingleHistogramView.h" 10 | 11 | @interface TLChartSingleHistogramView() 12 | 13 | 14 | @property (nonatomic,weak) CALayer * contentLayer; 15 | @property (nonatomic,assign)CGFloat allLineWidth; 16 | 17 | @property (nonatomic,weak)CALayer *animationLayer; //动画效果mask 18 | @property (nonatomic,strong)CABasicAnimation *animation; 19 | @end 20 | @implementation TLChartSingleHistogramView 21 | 22 | - (CABasicAnimation *)animation{ 23 | if (!_animation) { 24 | _animation = [CABasicAnimation animationWithKeyPath:@"position"]; 25 | _animation.duration = 0.8; 26 | _animation.fromValue = [NSValue valueWithCGPoint:_animationLayer.position]; 27 | _animation.toValue = [NSValue valueWithCGPoint:CGPointMake(_animationLayer.position.x +CGRectGetWidth(self.frame), _animationLayer.position.y)]; 28 | _animation.removedOnCompletion = NO; 29 | _animation.fillMode = kCAFillModeForwards; 30 | _animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];; 31 | } 32 | return _animation; 33 | } 34 | - (CALayer *)animationLayer{ 35 | if (!_animationLayer) { 36 | 37 | CALayer *animationLayer = [CALayer layer]; 38 | animationLayer.backgroundColor = [UIColor whiteColor].CGColor; 39 | animationLayer.frame = CGRectMake(_verTitleWidth, 0, CGRectGetWidth(self.frame) -_verTitleWidth, CGRectGetHeight(self.frame) -_horTitleHeight- _lineWidth); 40 | _animationLayer = animationLayer; 41 | } 42 | return _animationLayer; 43 | } 44 | -(instancetype)initWithFrame:(CGRect)frame{ 45 | 46 | if (self = [super initWithFrame:frame]) { 47 | 48 | _corner = 4; 49 | _verTitleWidth = 80; 50 | _horTitleHeight = 50; 51 | 52 | _titleColor = [UIColor blackColor]; 53 | _contentColor = [UIColor blackColor]; 54 | 55 | _verTitleFont = 15; 56 | _horTitleFont = 15; 57 | _contentFont = 12; 58 | 59 | _lineColor = [UIColor blackColor]; 60 | _lineWidth = 1; 61 | _extLineWidth = 3; 62 | 63 | } 64 | return self; 65 | } 66 | - (void)choseItemAction:(UITapGestureRecognizer *)tapGesture{ 67 | 68 | CGPoint tapPoint = [tapGesture locationInView:self]; 69 | CGFloat cellHeight = (CGRectGetHeight(self.frame) -_horTitleHeight)/self.verTitleArr.count; 70 | 71 | for (int i =0; i = _verTitleWidth && tapPoint.x <= _verTitleWidth +itemtWidth) && 76 | (tapPoint.y >= cellHeight/4 +cellHeight *i && tapPoint.y <= cellHeight *3/4 +cellHeight *i)) { 77 | 78 | if (self.clickBlock) { 79 | self.clickBlock(i); 80 | } 81 | return; 82 | } 83 | } 84 | } 85 | - (void)addAnimation{ 86 | 87 | [self.contentLayer addSublayer:self.animationLayer]; 88 | 89 | [self.animationLayer removeAnimationForKey:@"position-x"]; 90 | [self.animationLayer addAnimation:self.animation forKey:@"position-x"]; 91 | 92 | 93 | } 94 | - (void)layoutSubviews{ 95 | 96 | [super layoutSubviews]; 97 | [self.layer addSublayer:self.contentLayer]; 98 | 99 | UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(choseItemAction:)]; 100 | [self addGestureRecognizer:tap]; 101 | 102 | [self tl_layoutContent]; 103 | [self addAnimation]; 104 | 105 | } 106 | - (void)reloadData{ 107 | self.layer.contents = nil; 108 | [self tl_layoutContent]; 109 | [self addAnimation]; 110 | } 111 | - (CALayer *)contentLayer{ 112 | if (_contentLayer == nil) { 113 | CALayer * contentLayer = [CALayer layer]; 114 | contentLayer.backgroundColor = [UIColor clearColor].CGColor; 115 | contentLayer.frame = self.bounds; 116 | _contentLayer = contentLayer; 117 | } 118 | return _contentLayer; 119 | } 120 | - (void)tl_layoutContent{ 121 | 122 | //文字居中显示在画布上 123 | NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 124 | paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;// 这个属性是能够画字符的时候换行 125 | paragraphStyle.alignment = NSTextAlignmentCenter; 126 | 127 | 128 | UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale); 129 | CGContextRef context = UIGraphicsGetCurrentContext(); 130 | CGContextSetLineWidth(context, _lineWidth); 131 | 132 | 133 | [_lineColor setStroke]; 134 | // 画竖线 135 | CGContextSetLineWidth(context, _lineWidth); 136 | CGContextMoveToPoint(context, _verTitleWidth, 0); 137 | CGContextAddLineToPoint(context, _verTitleWidth, CGRectGetHeight(self.frame) -_horTitleHeight); 138 | CGContextStrokePath(context); 139 | 140 | 141 | //画横线 142 | CGSize lastStrSize = [[self.horTitleArr lastObject] sizeWithAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:_horTitleFont],NSForegroundColorAttributeName:_titleColor,NSParagraphStyleAttributeName:paragraphStyle}]; 143 | _allLineWidth = CGRectGetWidth(self.frame) -_verTitleWidth -lastStrSize.width/2; 144 | 145 | CGContextSetLineWidth(context, _lineWidth); 146 | CGContextMoveToPoint(context, _verTitleWidth, CGRectGetHeight(self.frame) -_horTitleHeight); 147 | CGContextAddLineToPoint(context, _verTitleWidth +_allLineWidth, CGRectGetHeight(self.frame) -_horTitleHeight); 148 | CGContextStrokePath(context); 149 | 150 | //画额外的横线 151 | CGFloat cellHeight = (CGRectGetHeight(self.frame) -_horTitleHeight)/self.verTitleArr.count; 152 | for (int i = 0; i < self.verTitleArr.count +1; i ++) { 153 | 154 | CGContextSetLineWidth(context, _lineWidth); 155 | CGContextMoveToPoint(context, _verTitleWidth -_extLineWidth, cellHeight *i); 156 | CGContextAddLineToPoint(context, _verTitleWidth, cellHeight *i); 157 | CGContextStrokePath(context); 158 | } 159 | //画额外的竖线 160 | CGFloat cellWidth = _allLineWidth/(self.horTitleArr.count -1); 161 | for (int i = 0; i < self.horTitleArr.count; i ++) { 162 | 163 | CGContextSetLineWidth(context, _lineWidth); 164 | CGContextMoveToPoint(context, _verTitleWidth +cellWidth *i, CGRectGetHeight(self.frame) -_horTitleHeight); 165 | CGContextAddLineToPoint(context, _verTitleWidth +cellWidth *i, CGRectGetHeight(self.frame) -_horTitleHeight +_extLineWidth); 166 | CGContextStrokePath(context); 167 | } 168 | 169 | //画竖向的标题 170 | CGFloat allHorExtHeight = 0; 171 | for (int i =0; i 0) { 204 | contentColor = self.dataColorArr[i]; 205 | } 206 | [contentColor setFill]; 207 | 208 | CGFloat itemWidth = _allLineWidth *[self.dataArr[i] floatValue]; 209 | 210 | CGContextMoveToPoint(context, _verTitleWidth, cellHeight/4 +cellHeight *i); 211 | 212 | CGContextAddArcToPoint(context, _verTitleWidth +itemWidth, cellHeight/4 +cellHeight *i, _verTitleWidth +itemWidth, cellHeight/4 +cellHeight *i +_corner *2, _corner); 213 | CGContextAddArcToPoint(context, _verTitleWidth +itemWidth, cellHeight *3/4 +cellHeight *i, _verTitleWidth +itemWidth -_corner *2, cellHeight *3/4 +cellHeight *i, _corner); 214 | 215 | CGContextAddLineToPoint(context,_verTitleWidth, cellHeight *3/4 +cellHeight *i); 216 | CGContextFillPath(context); 217 | 218 | //画柱状图里面的文字 219 | NSDictionary *attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:_contentFont],NSForegroundColorAttributeName:_contentColor,NSParagraphStyleAttributeName:paragraphStyle}; 220 | 221 | NSString *title = self.dataTitleArr[i]; 222 | CGSize strSize = [title sizeWithAttributes:attributes]; 223 | [title drawInRect:CGRectMake(_verTitleWidth, cellHeight/4 +cellHeight *i +(cellHeight/2 -strSize.height)/2, itemWidth, strSize.height) withAttributes:attributes]; 224 | } 225 | 226 | 227 | 228 | UIImage * currentImage = UIGraphicsGetImageFromCurrentImageContext(); 229 | UIGraphicsEndImageContext(); 230 | self.contentLayer.contents = (__bridge id _Nullable)(currentImage.CGImage); 231 | 232 | } 233 | @end 234 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartTableView.h 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/1. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #define P_M(x,y) CGPointMake(x, y) 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface TLChartTableView : UIView 16 | 17 | @property (nonatomic, strong) UIColor *lineColor;//line的颜色 18 | @property (nonatomic, assign) CGFloat lineWidth;//line的粗细 19 | @property (nonatomic, strong) NSArray *dataArr;//数据 20 | 21 | @property (nonatomic, strong) UIColor *horLine0bgColor;//第一行的背景色 22 | @property (nonatomic, assign) CGFloat horLine0Font;//第一行的字号 23 | @property (nonatomic, strong) UIColor *horLine0TextColor;//第一行的字色 24 | @property (nonatomic, strong) NSArray *horWidthProArr;//行宽的比重 25 | 26 | @property (nonatomic, strong) UIColor *verLine0bgColor;//第一列的背景色 27 | @property (nonatomic, assign) CGFloat verLine0Font;//第一列的字号 28 | @property (nonatomic, strong) UIColor *verLine0TextColor;//第一列的字色 29 | @property (nonatomic, strong) NSArray *verHeightProArr;//列长的比重 30 | 31 | @property (nonatomic, assign) CGFloat defaultFont;//非第一行、第一列的字号 32 | @property (nonatomic, strong) UIColor *defaultTextColor;//非第一行、第一列的字色 33 | 34 | @property (nonatomic,copy) void(^ clickBlock)(NSInteger indexX ,NSInteger indexY); 35 | - (void)reloadData; 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /TLChart/TLChartTool/TLChartTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLChartTableView.m 3 | // ChartTableView 4 | // 5 | // Created by hello on 2019/4/1. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "TLChartTableView.h" 10 | 11 | @interface TLChartTableView() 12 | 13 | 14 | @property (nonatomic,weak) CALayer * contentLayer; 15 | @end 16 | 17 | @implementation TLChartTableView 18 | 19 | -(instancetype)initWithFrame:(CGRect)frame{ 20 | 21 | if (self = [super initWithFrame:frame]) { 22 | 23 | _lineColor = [UIColor grayColor]; 24 | _lineWidth = 1.0; 25 | 26 | _horLine0bgColor = [UIColor colorWithRed:82.0 / 255.0 green:116.0 / 255.0 blue:188.0 / 255.0 alpha:1.0f]; 27 | _horLine0Font = 15; 28 | _horLine0TextColor = [UIColor blackColor]; 29 | 30 | _verLine0bgColor = [UIColor colorWithRed:242.0 / 255.0 green:197.0 / 255.0 blue:117.0 / 255.0 alpha:1.0f]; 31 | _verLine0Font = 15; 32 | _verLine0TextColor = [UIColor blackColor]; 33 | 34 | _defaultFont = 15; 35 | _defaultTextColor = [UIColor blackColor]; 36 | 37 | } 38 | return self; 39 | } 40 | - (void)choseItemAction:(UITapGestureRecognizer *)tapGesture{ 41 | 42 | CGPoint tapPoint = [tapGesture locationInView:self]; 43 | 44 | CGFloat pointY = 0; 45 | for (int i =0; self.verHeightProArr.count; i ++) { 46 | 47 | CGFloat pointX = 0; 48 | for (int j =0; j = pointX && tapPoint.x <= pointX +[self.horWidthProArr[j] floatValue]) && 51 | (tapPoint.y >= pointY && tapPoint.y <= pointY +[self.verHeightProArr[i] floatValue])) { 52 | 53 | if (self.clickBlock) { 54 | self.clickBlock(j, i); 55 | } 56 | return; 57 | } 58 | pointX = pointX +[self.horWidthProArr[j] floatValue]; 59 | } 60 | pointY = pointY +[self.verHeightProArr[i] floatValue]; 61 | } 62 | } 63 | - (void)addAnimation{ 64 | 65 | self.transform = CGAffineTransformMakeScale(0.8, 0.8); 66 | [UIView animateWithDuration:0.8 delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseOut animations:^{ 67 | 68 | self.transform = CGAffineTransformIdentity; 69 | } completion:^(BOOL finished) { 70 | 71 | }]; 72 | } 73 | - (void)layoutSubviews{ 74 | 75 | [super layoutSubviews]; 76 | [self.layer addSublayer:self.contentLayer]; 77 | 78 | UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(choseItemAction:)]; 79 | [self addGestureRecognizer:tap]; 80 | 81 | [self tl_layoutContent]; 82 | [self addAnimation]; 83 | } 84 | - (void)reloadData{ 85 | self.layer.contents = nil; 86 | [self tl_layoutContent]; 87 | [self addAnimation]; 88 | // [self layoutSubviews]; 89 | } 90 | - (CALayer *)contentLayer{ 91 | if (_contentLayer == nil) { 92 | CALayer * contentLayer = [CALayer layer]; 93 | contentLayer.backgroundColor = [UIColor clearColor].CGColor; 94 | contentLayer.frame = self.bounds; 95 | _contentLayer = contentLayer; 96 | } 97 | return _contentLayer; 98 | } 99 | - (void)tl_layoutContent{ 100 | 101 | //文字居中显示在画布上 102 | NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 103 | paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;// 这个属性是能够画字符的时候换行 104 | paragraphStyle.alignment = NSTextAlignmentCenter; 105 | 106 | 107 | UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale); 108 | CGContextRef context = UIGraphicsGetCurrentContext(); 109 | CGContextSetLineWidth(context, _lineWidth); 110 | 111 | 112 | CGFloat titleWidth0 = [self.horWidthProArr[0] floatValue]; 113 | CGFloat titleHeight0 = [self.verHeightProArr[0] floatValue]; 114 | 115 | [_horLine0bgColor setFill]; 116 | // 画横向标题的背景 117 | CGContextMoveToPoint(context, 0, 0); 118 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame), 0); 119 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame), titleHeight0); 120 | CGContextAddLineToPoint(context, 0, titleHeight0); 121 | CGContextFillPath(context); 122 | 123 | [_verLine0bgColor setFill]; 124 | // 画竖向标题的背景 125 | CGContextMoveToPoint(context, 0, titleHeight0); 126 | CGContextAddLineToPoint(context, titleWidth0, titleHeight0); 127 | CGContextAddLineToPoint(context, titleWidth0, CGRectGetHeight(self.frame)); 128 | CGContextAddLineToPoint(context, 0, CGRectGetHeight(self.frame)); 129 | CGContextFillPath(context); 130 | 131 | 132 | [_lineColor setStroke];/// 133 | // 画最外面的四边形 134 | CGContextMoveToPoint(context, 0, 0); 135 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame) -_lineWidth/2, 0); 136 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame) -_lineWidth/2, CGRectGetHeight(self.frame) -_lineWidth/2); 137 | CGContextAddLineToPoint(context, 0, CGRectGetHeight(self.frame) -_lineWidth/2); 138 | CGContextAddLineToPoint(context, 0, 0); 139 | CGContextStrokePath(context); 140 | 141 | CGFloat verAllHeight = 0; 142 | // 画横线 143 | for (int i = 1; i < self.verHeightProArr.count; i ++) { 144 | 145 | verAllHeight = verAllHeight +[self.verHeightProArr[i -1] floatValue]; 146 | CGContextSetLineWidth(context, _lineWidth); 147 | CGContextMoveToPoint(context, 0, verAllHeight); 148 | CGContextAddLineToPoint(context, CGRectGetWidth(self.frame), verAllHeight); 149 | CGContextStrokePath(context); 150 | } 151 | 152 | // 画竖线 153 | CGFloat horAllWidth = 0; 154 | for (int i = 1; i < self.horWidthProArr.count; i ++) { 155 | 156 | horAllWidth = horAllWidth +[self.horWidthProArr[i -1] floatValue]; 157 | CGContextSetLineWidth(context, _lineWidth); 158 | CGContextMoveToPoint(context, horAllWidth, 0); 159 | CGContextAddLineToPoint(context, horAllWidth, CGRectGetHeight(self.frame)); 160 | CGContextStrokePath(context); 161 | } 162 | 163 | // 画内容 164 | 165 | CGFloat pointY = 0; 166 | for (int i = 0; i < self.verHeightProArr.count; i++) { 167 | 168 | CGFloat titleHeight = [self.verHeightProArr[i] floatValue]; 169 | NSArray *horTitleArr = self.dataArr[i]; 170 | 171 | CGFloat pointX = 0; 172 | for (int j = 0; j < self.horWidthProArr.count; j++) { 173 | 174 | CGFloat titleWidth = [self.horWidthProArr[j] floatValue]; 175 | NSString *title = horTitleArr[j]; 176 | 177 | NSArray *firArr = [title componentsSeparatedByString:@"|"]; 178 | 179 | if (2 == firArr.count) { 180 | // 画斜线 181 | CGContextMoveToPoint(context, pointX, pointY); 182 | CGContextAddLineToPoint(context, titleWidth, titleHeight); 183 | CGContextStrokePath(context); 184 | 185 | CGFloat pointY0 = (titleHeight/2 -_horLine0Font)/2; 186 | CGFloat pointY1 = titleHeight/2 +(titleHeight/2 -_horLine0Font)/2; 187 | 188 | [firArr[0] drawInRect:CGRectMake(titleWidth/2 ,pointY0, titleWidth/2, titleHeight/2) withAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:_horLine0Font ],NSForegroundColorAttributeName:_horLine0TextColor,NSParagraphStyleAttributeName:paragraphStyle}]; 189 | 190 | [firArr[1] drawInRect:CGRectMake(pointX, pointY1, titleWidth/2, titleHeight/2) withAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:_horLine0Font ],NSForegroundColorAttributeName:_horLine0TextColor,NSParagraphStyleAttributeName:paragraphStyle}]; 191 | 192 | 193 | }else{ 194 | 195 | NSDictionary *attributes; 196 | if (0 == i) { 197 | 198 | attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:_horLine0Font],NSForegroundColorAttributeName:_horLine0TextColor,NSParagraphStyleAttributeName:paragraphStyle}; 199 | 200 | 201 | }else if (0 == j){ 202 | 203 | attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:_verLine0Font],NSForegroundColorAttributeName:_verLine0TextColor,NSParagraphStyleAttributeName:paragraphStyle}; 204 | 205 | }else{ 206 | 207 | attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:_defaultFont],NSForegroundColorAttributeName:_defaultTextColor,NSParagraphStyleAttributeName:paragraphStyle}; 208 | } 209 | CGSize strSize = [title sizeWithAttributes:attributes]; 210 | CGFloat newPointY = pointY +(titleHeight -strSize.height)/2; 211 | [title drawInRect:CGRectMake(pointX, newPointY, titleWidth, strSize.height) withAttributes:attributes]; 212 | 213 | } 214 | pointX = pointX +[self.horWidthProArr[j] floatValue]; 215 | } 216 | pointY = pointY +[self.verHeightProArr[i] floatValue]; 217 | } 218 | 219 | UIImage * currentImage = UIGraphicsGetImageFromCurrentImageContext(); 220 | UIGraphicsEndImageContext(); 221 | self.contentLayer.contents = (__bridge id _Nullable)(currentImage.CGImage); 222 | 223 | 224 | 225 | } 226 | 227 | @end 228 | -------------------------------------------------------------------------------- /TLChart/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /TLChart/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "ViewController1.h" 11 | 12 | @interface ViewController () 13 | 14 | @property (nonatomic ,strong)UITableView *tableView; 15 | @property (nonatomic ,copy )NSMutableArray *dataArr; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (NSMutableArray *)dataArr{ 22 | if (!_dataArr) { 23 | _dataArr = [[NSMutableArray alloc]initWithArray:@[@"饼图/速率图0",@"饼图/速率图1",@"表图",@"单柱状图",@"双柱状图"]]; 24 | } 25 | return _dataArr; 26 | } 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view. 30 | 31 | self.title = @"报表"; 32 | self.view.backgroundColor = [UIColor whiteColor]; 33 | 34 | self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(10, NavBarHeight, TLDeviceWidth -20, TLDeviceHeight -(NavBarHeight +TabBarHeight)) style:UITableViewStylePlain]; 35 | self.tableView.estimatedRowHeight = 0; 36 | self.tableView.estimatedSectionHeaderHeight = 0; 37 | self.tableView.estimatedSectionFooterHeight = 0; 38 | self.tableView.delegate = self; 39 | self.tableView.dataSource = self; 40 | // self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 41 | self.tableView.showsVerticalScrollIndicator = YES; 42 | self.tableView.backgroundColor = [UIColor whiteColor]; 43 | [self.view addSubview:self.tableView]; 44 | 45 | 46 | 47 | } 48 | 49 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 50 | return self.dataArr.count; 51 | } 52 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 53 | return 100; 54 | } 55 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 56 | 57 | static NSString * const cellID = @"UITableViewCell"; 58 | UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 59 | if (cell == nil) { 60 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; 61 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 62 | } 63 | cell.textLabel.text = self.dataArr[indexPath.row]; 64 | cell.textLabel.textColor = [UIColor redColor]; 65 | cell.textLabel.font = [UIFont boldSystemFontOfSize:20]; 66 | return cell; 67 | } 68 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 69 | 70 | ViewController1 *vc = [ViewController1 new]; 71 | vc.title = self.dataArr[indexPath.row]; 72 | vc.hidesBottomBarWhenPushed = YES; 73 | [self.navigationController pushViewController:vc animated:YES]; 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /TLChart/ViewController1.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController1.h 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ViewController1 : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /TLChart/ViewController1.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController1.m 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. All rights reserved. 7 | // 8 | 9 | #import "ViewController1.h" 10 | #import "TLChartRateView.h" 11 | #import "TLChartRateView1.h" 12 | #import "TLChartTableView.h" 13 | #import "TLChartSingleHistogramView.h" 14 | #import "TLChartDoubleHistogramView.h" 15 | 16 | @interface ViewController1 () 17 | 18 | @property (nonatomic ,strong)UILabel *lab; 19 | @property (nonatomic ,strong)TLChartRateView *rateView; 20 | @property (nonatomic ,strong)TLChartRateView1 *rateView1; 21 | @property (nonatomic ,strong)TLChartTableView *tableView; 22 | @property (nonatomic ,strong)TLChartSingleHistogramView *singleHistogramView; 23 | @property (nonatomic ,strong)TLChartDoubleHistogramView *doubleHistogramView; 24 | 25 | @end 26 | 27 | @implementation ViewController1 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | // Do any additional setup after loading the view. 32 | 33 | self.view.backgroundColor = [UIColor whiteColor]; 34 | [self initUI]; 35 | [self createBtn]; 36 | 37 | } 38 | - (void)createBtn{ 39 | 40 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 41 | btn.backgroundColor = [UIColor redColor]; 42 | btn.frame = CGRectMake(50, 50 +NavBarHeight, 100, 40); 43 | [btn setTitle:@"刷新数据" forState:UIControlStateNormal]; 44 | [btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside]; 45 | [self.view addSubview:btn]; 46 | 47 | self.lab = [UILabel new]; 48 | self.lab.frame = CGRectMake(0, TLDeviceHeight -200, TLDeviceWidth, 50); 49 | self.lab.textAlignment = 1; 50 | [self.view addSubview:self.lab]; 51 | } 52 | - (void)click:(UIButton *)btn{ 53 | 54 | if ([@"饼图/速率图0" isEqualToString:self.title]) { 55 | 56 | self.rateView.arcData = @"0.7"; 57 | [self.rateView reloadData]; 58 | 59 | 60 | }else if ([@"饼图/速率图1" isEqualToString:self.title]){ 61 | 62 | self.rateView1.arcData = 0.9; 63 | [self.rateView1 reloadData]; 64 | 65 | }else if ([@"表图" isEqualToString:self.title]){ 66 | 67 | NSArray *arr0 = @[@"宠物|姓名",@"狗",@"🐈",@"老鼠",@"🦁"]; 68 | NSArray *arr1 = @[@"张三",@"10",@"0",@"1",@"20"]; 69 | NSArray *arr2 = @[@"李四",@"0",@"60",@"60",@"20"]; 70 | NSArray *arr3 = @[@"王老五",@"7",@"30",@"5",@"15"]; 71 | NSArray *dataArr = @[arr0,arr1,arr2,arr3]; 72 | 73 | self.tableView.dataArr = dataArr; 74 | [self.tableView reloadData]; 75 | 76 | }else if ([@"单柱状图" isEqualToString:self.title]){ 77 | 78 | self.singleHistogramView.verTitleArr = @[@"战争机器",@"钢铁侠",@"蜘蛛侠"]; 79 | self.singleHistogramView.horTitleArr = @[@"0",@"50",@"100",@"150"]; 80 | self.singleHistogramView.dataArr = @[@(0.2),@(0.8),@(0.5)]; 81 | self.singleHistogramView.dataTitleArr = @[@"😃",@"😜",@"😭"]; 82 | [self.singleHistogramView reloadData]; 83 | 84 | }else if ([@"双柱状图" isEqualToString:self.title]){ 85 | 86 | self.doubleHistogramView.data0Arr = @[@(53/80.0),@(44/80.0),@(77/80.0)]; 87 | self.doubleHistogramView.data1Arr = @[@(66/80.0),@(48/80.0),@(74/80.0)]; 88 | self.doubleHistogramView.dataTitle0Arr = @[@"上月53",@"上月44",@"上月77"]; 89 | self.doubleHistogramView.dataTitle1Arr = @[@"本月66",@"本月48",@"本月74"]; 90 | [self.doubleHistogramView reloadData]; 91 | 92 | } 93 | 94 | } 95 | - (void)initUI{ 96 | 97 | if ([@"饼图/速率图0" isEqualToString:self.title]) { 98 | 99 | [self initTLChartRateView0]; 100 | 101 | }else if ([@"饼图/速率图1" isEqualToString:self.title]){ 102 | 103 | [self initTLChartRateView1]; 104 | 105 | }else if ([@"表图" isEqualToString:self.title]){ 106 | 107 | [self initTLChartTableView]; 108 | 109 | }else if ([@"单柱状图" isEqualToString:self.title]){ 110 | 111 | [self initTLChartSingleHistogramView]; 112 | 113 | }else if ([@"双柱状图" isEqualToString:self.title]){ 114 | 115 | [self initTLChartDoubleHistogramView]; 116 | } 117 | 118 | } 119 | - (void)initTLChartRateView0{ 120 | 121 | self.rateView = [TLChartRateView new]; 122 | self.rateView.frame = CGRectMake((TLDeviceWidth -RateViewWidth)/2, 150 +NavBarHeight, RateViewWidth, RateViewHeight); 123 | [self.view addSubview:self.rateView]; 124 | 125 | } 126 | - (void)initTLChartRateView1{ 127 | 128 | self.rateView1 = [TLChartRateView1 new]; 129 | self.rateView1.frame = CGRectMake((TLDeviceWidth -RateViewWidth)/2, 150 +NavBarHeight, RateViewWidth, RateViewHeight); 130 | [self.view addSubview:self.rateView1]; 131 | 132 | } 133 | - (void)initTLChartTableView{ 134 | 135 | NSArray *arr0 = @[@"学科|姓名",@"数学",@"语文",@"英语",@"物理"]; 136 | NSArray *arr1 = @[@"张三",@"100",@"50",@"",@"70"]; 137 | NSArray *arr2 = @[@"李四",@"",@"60",@"100",@"0"]; 138 | NSArray *arr3 = @[@"王老五",@"7",@"0",@"",@"70"]; 139 | NSArray *dataArr = @[arr0,arr1,arr2,arr3]; 140 | 141 | CGFloat width = TLDeviceWidth -20; 142 | self.tableView = [TLChartTableView new]; 143 | self.tableView.frame = CGRectMake(10, 150 +NavBarHeight, width, 300); 144 | self.tableView.dataArr = dataArr; 145 | self.tableView.horWidthProArr = @[@(width *0.2),@(width *0.15),@(width *0.25),@(width *0.1),@(width *0.3)]; 146 | self.tableView.verHeightProArr = @[@(90),@(70),@(80),@(60)]; 147 | [self.view addSubview:self.tableView]; 148 | 149 | WS(weakSelf); 150 | self.tableView.clickBlock = ^(NSInteger indexX, NSInteger indexY) { 151 | SS(strongSelf); 152 | 153 | NSLog(@"%ld------%ld",(long)indexX,(long)indexY); 154 | strongSelf.lab.text = [NSString stringWithFormat:@"点击了:(X:%ld-----Y:%ld)",(long)indexX,(long)indexY]; 155 | }; 156 | } 157 | - (void)initTLChartSingleHistogramView{ 158 | 159 | 160 | UIColor *color0 = [UIColor colorWithRed:121.0 / 255.0 green:134.0 / 255.0 blue:142.0 / 255.0 alpha:1.0f]; 161 | UIColor *color1 = [UIColor colorWithRed:88.0 / 255.0 green:75.0 / 255.0 blue:103.0 / 255.0 alpha:1.0f]; 162 | UIColor *color2 = [UIColor colorWithRed:82.0 / 255.0 green:116.0 / 255.0 blue:188.0 / 255.0 alpha:1.0f]; 163 | 164 | self.singleHistogramView = [TLChartSingleHistogramView new]; 165 | self.singleHistogramView.frame = CGRectMake(20, 150 +NavBarHeight, 350, 300); 166 | self.singleHistogramView.verTitleArr = @[@"张三",@"李四",@"王老五"]; 167 | self.singleHistogramView.horTitleArr = @[@"50",@"100",@"150",@"200"]; 168 | self.singleHistogramView.dataArr = @[@(0.7),@(0.2),@(1)]; 169 | self.singleHistogramView.dataTitleArr = @[@"数据0",@"数据1",@"数据2"]; 170 | self.singleHistogramView.dataColorArr = @[color0,color1,color2]; 171 | [self.view addSubview:self.singleHistogramView]; 172 | 173 | WS(weakSelf); 174 | self.singleHistogramView.clickBlock = ^(NSInteger index) { 175 | SS(strongSelf); 176 | 177 | NSLog(@"----%ld",(long)index); 178 | strongSelf.lab.text = [NSString stringWithFormat:@"点击了:----%ld",(long)index]; 179 | }; 180 | } 181 | - (void)initTLChartDoubleHistogramView{ 182 | 183 | UIColor *color0 = [UIColor colorWithRed:88.0 / 255.0 green:75.0 / 255.0 blue:103.0 / 255.0 alpha:1.0f]; 184 | UIColor *color1 = [UIColor colorWithRed:121.0 / 255.0 green:134.0 / 255.0 blue:142.0 / 255.0 alpha:1.0f]; 185 | 186 | 187 | self.doubleHistogramView = [TLChartDoubleHistogramView new]; 188 | self.doubleHistogramView.frame = CGRectMake(20, 150 +NavBarHeight, 350, 300); 189 | self.doubleHistogramView.verTitleArr = @[@"进货量",@"销售量",@"囤货量"]; 190 | self.doubleHistogramView.horTitleArr = @[@"0",@"20",@"40",@"60",@"80"]; 191 | self.doubleHistogramView.data0Arr = @[@(76/80.0),@(74/80.0),@(50/80.0)]; 192 | self.doubleHistogramView.data1Arr = @[@(72/80.0),@(73/80.0),@(45/80.0)]; 193 | self.doubleHistogramView.dataTitle0Arr = @[@"上月76",@"上月74",@"上月50"]; 194 | self.doubleHistogramView.dataTitle1Arr = @[@"本月72",@"本月73",@"本月45"]; 195 | self.doubleHistogramView.dataColor0Arr = @[color0,color0,color0]; 196 | self.doubleHistogramView.dataColor1Arr = @[color1,color1,color1]; 197 | [self.view addSubview:self.doubleHistogramView]; 198 | 199 | WS(weakSelf); 200 | self.doubleHistogramView.clickBlock = ^(NSInteger secIndex, NSInteger rowIndex) { 201 | SS(strongSelf); 202 | 203 | NSLog(@"%ld------%ld",(long)secIndex,(long)rowIndex); 204 | strongSelf.lab.text = [NSString stringWithFormat:@"点击了:(数据源:%ld---row:%ld)",(long)secIndex,(long)rowIndex]; 205 | }; 206 | 207 | } 208 | 209 | 210 | @end 211 | -------------------------------------------------------------------------------- /TLChart/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TLChart 4 | // 5 | // Created by hello on 2019/5/7. 6 | // Copyright © 2019 tanglei. 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 | --------------------------------------------------------------------------------