├── .gitignore ├── .swift-version ├── CoordinateAxisChart.podspec ├── CoordinateAxisChart.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── zhuhuiping.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── zhuhuiping.xcuserdatad │ └── xcschemes │ ├── CoordinateAxisChart.xcscheme │ └── xcschememanagement.plist ├── CoordinateAxisChart ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CoordinateAxisChart │ └── CoordinateAxisChart.swift ├── Info.plist └── ViewController.swift ├── CoordinateAxisChartDemo.gif ├── CoordinateAxisChartTests ├── CoordinateAxisChartTests.swift └── Info.plist ├── CoordinateAxisChartUITests ├── CoordinateAxisChartUITests.swift └── Info.plist ├── README.md ├── chart.png └── charttwo.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Xcode template 3 | # Xcode 4 | # 5 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData/ 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | 22 | ## Other 23 | *.moved-aside 24 | *.xccheckout 25 | *.xcscmblueprint 26 | ### macOS template 27 | *.DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Icon must end with two \r 32 | Icon 33 | 34 | 35 | # Thumbnails 36 | ._* 37 | 38 | # Files that might appear in the root of a volume 39 | .DocumentRevisions-V100 40 | .fseventsd 41 | .Spotlight-V100 42 | .TemporaryItems 43 | .Trashes 44 | .VolumeIcon.icns 45 | .com.apple.timemachine.donotpresent 46 | 47 | # Directories potentially created on remote AFP share 48 | .AppleDB 49 | .AppleDesktop 50 | Network Trash Folder 51 | Temporary Items 52 | .apdisk 53 | ### Swift template 54 | # Xcode 55 | # 56 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 57 | 58 | ## Build generated 59 | 60 | ## Various settings 61 | 62 | ## Other 63 | 64 | ## Obj-C/Swift specific 65 | *.hmap 66 | *.ipa 67 | *.dSYM.zip 68 | *.dSYM 69 | 70 | ## Playgrounds 71 | timeline.xctimeline 72 | playground.xcworkspace 73 | 74 | # Swift Package Manager 75 | # 76 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 77 | # Packages/ 78 | # Package.pins 79 | .build/ 80 | 81 | # CocoaPods 82 | # 83 | # We recommend against adding the Pods directory to your .gitignore. However 84 | # you should judge for yourself, the pros and cons are mentioned at: 85 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 86 | # 87 | # Pods/ 88 | 89 | # Carthage 90 | # 91 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 92 | # Carthage/Checkouts 93 | 94 | Carthage/Build 95 | 96 | # fastlane 97 | # 98 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 99 | # screenshots whenever they are needed. 100 | # For more information about the recommended setup visit: 101 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 102 | 103 | fastlane/report.xml 104 | fastlane/Preview.html 105 | fastlane/screenshots 106 | fastlane/test_output 107 | ### Objective-C template 108 | # Xcode 109 | # 110 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 111 | 112 | ## Build generated 113 | 114 | ## Various settings 115 | 116 | ## Other 117 | 118 | ## Obj-C/Swift specific 119 | 120 | # CocoaPods 121 | # 122 | # We recommend against adding the Pods directory to your .gitignore. However 123 | # you should judge for yourself, the pros and cons are mentioned at: 124 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 125 | # 126 | # Pods/ 127 | 128 | # Carthage 129 | # 130 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 131 | # Carthage/Checkouts 132 | 133 | 134 | # fastlane 135 | # 136 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 137 | # screenshots whenever they are needed. 138 | # For more information about the recommended setup visit: 139 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 140 | 141 | 142 | # Code Injection 143 | # 144 | # After new code Injection tools there's a generated folder /iOSInjectionProject 145 | # https://github.com/johnno1962/injectionforxcode 146 | 147 | iOSInjectionProject/ 148 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /CoordinateAxisChart.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "CoordinateAxisChart" 4 | s.version = "1.0.1" 5 | s.summary = "A short description of CoordinateAxisChart." 6 | s.homepage = "https://github.com/CrystalMarch/CoordinateAxisChart" 7 | s.license = { :type => "MIT", :file => "FILE_LICENSE" } 8 | s.author = { "Crystal" => "zhuhuiping@shinetechchina.com" } 9 | s.platform = :ios 10 | s.platform = :ios, "8.0" 11 | s.source = { :git => "https://github.com/CrystalMarch/CoordinateAxisChart.git", :tag => "1.0.1" } 12 | s.source_files = "CoordinateAxisChart/CoordinateAxisChart/*.swift", "CoordinateAxisChart/CoordinateAxisChart/**/*.swift" 13 | s.exclude_files = "Classes/Exclude" 14 | s.frameworks = "Foundation", "UIKit" 15 | s.requires_arc = true 16 | end 17 | -------------------------------------------------------------------------------- /CoordinateAxisChart.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 355C80D11EA9D8ED001E83AA /* CoordinateAxisChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 355C80D01EA9D8ED001E83AA /* CoordinateAxisChart.swift */; }; 11 | 358694731E9F78C700F052D2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 358694721E9F78C700F052D2 /* AppDelegate.swift */; }; 12 | 358694751E9F78C700F052D2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 358694741E9F78C700F052D2 /* ViewController.swift */; }; 13 | 358694781E9F78C700F052D2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 358694761E9F78C700F052D2 /* Main.storyboard */; }; 14 | 3586947A1E9F78C700F052D2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 358694791E9F78C700F052D2 /* Assets.xcassets */; }; 15 | 3586947D1E9F78C700F052D2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3586947B1E9F78C700F052D2 /* LaunchScreen.storyboard */; }; 16 | 358694881E9F78C700F052D2 /* CoordinateAxisChartTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 358694871E9F78C700F052D2 /* CoordinateAxisChartTests.swift */; }; 17 | 358694931E9F78C700F052D2 /* CoordinateAxisChartUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 358694921E9F78C700F052D2 /* CoordinateAxisChartUITests.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | 358694841E9F78C700F052D2 /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = 358694671E9F78C700F052D2 /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = 3586946E1E9F78C700F052D2; 26 | remoteInfo = CoordinateAxisChart; 27 | }; 28 | 3586948F1E9F78C700F052D2 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 358694671E9F78C700F052D2 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 3586946E1E9F78C700F052D2; 33 | remoteInfo = CoordinateAxisChart; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 355C80D01EA9D8ED001E83AA /* CoordinateAxisChart.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CoordinateAxisChart.swift; path = CoordinateAxisChart/CoordinateAxisChart.swift; sourceTree = ""; }; 39 | 3586946F1E9F78C700F052D2 /* CoordinateAxisChart.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoordinateAxisChart.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 358694721E9F78C700F052D2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 41 | 358694741E9F78C700F052D2 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 42 | 358694771E9F78C700F052D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 43 | 358694791E9F78C700F052D2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 44 | 3586947C1E9F78C700F052D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 3586947E1E9F78C700F052D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 358694831E9F78C700F052D2 /* CoordinateAxisChartTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoordinateAxisChartTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 358694871E9F78C700F052D2 /* CoordinateAxisChartTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinateAxisChartTests.swift; sourceTree = ""; }; 48 | 358694891E9F78C700F052D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 3586948E1E9F78C700F052D2 /* CoordinateAxisChartUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoordinateAxisChartUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 358694921E9F78C700F052D2 /* CoordinateAxisChartUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinateAxisChartUITests.swift; sourceTree = ""; }; 51 | 358694941E9F78C700F052D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 3586946C1E9F78C700F052D2 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | 358694801E9F78C700F052D2 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | 3586948B1E9F78C700F052D2 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 358694661E9F78C700F052D2 = { 80 | isa = PBXGroup; 81 | children = ( 82 | 358694711E9F78C700F052D2 /* CoordinateAxisChart */, 83 | 358694861E9F78C700F052D2 /* CoordinateAxisChartTests */, 84 | 358694911E9F78C700F052D2 /* CoordinateAxisChartUITests */, 85 | 358694701E9F78C700F052D2 /* Products */, 86 | ); 87 | sourceTree = ""; 88 | }; 89 | 358694701E9F78C700F052D2 /* Products */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 3586946F1E9F78C700F052D2 /* CoordinateAxisChart.app */, 93 | 358694831E9F78C700F052D2 /* CoordinateAxisChartTests.xctest */, 94 | 3586948E1E9F78C700F052D2 /* CoordinateAxisChartUITests.xctest */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 358694711E9F78C700F052D2 /* CoordinateAxisChart */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 358694721E9F78C700F052D2 /* AppDelegate.swift */, 103 | 358694741E9F78C700F052D2 /* ViewController.swift */, 104 | 355C80D01EA9D8ED001E83AA /* CoordinateAxisChart.swift */, 105 | 358694761E9F78C700F052D2 /* Main.storyboard */, 106 | 358694791E9F78C700F052D2 /* Assets.xcassets */, 107 | 3586947B1E9F78C700F052D2 /* LaunchScreen.storyboard */, 108 | 3586947E1E9F78C700F052D2 /* Info.plist */, 109 | ); 110 | path = CoordinateAxisChart; 111 | sourceTree = ""; 112 | }; 113 | 358694861E9F78C700F052D2 /* CoordinateAxisChartTests */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 358694871E9F78C700F052D2 /* CoordinateAxisChartTests.swift */, 117 | 358694891E9F78C700F052D2 /* Info.plist */, 118 | ); 119 | path = CoordinateAxisChartTests; 120 | sourceTree = ""; 121 | }; 122 | 358694911E9F78C700F052D2 /* CoordinateAxisChartUITests */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 358694921E9F78C700F052D2 /* CoordinateAxisChartUITests.swift */, 126 | 358694941E9F78C700F052D2 /* Info.plist */, 127 | ); 128 | path = CoordinateAxisChartUITests; 129 | sourceTree = ""; 130 | }; 131 | /* End PBXGroup section */ 132 | 133 | /* Begin PBXNativeTarget section */ 134 | 3586946E1E9F78C700F052D2 /* CoordinateAxisChart */ = { 135 | isa = PBXNativeTarget; 136 | buildConfigurationList = 358694971E9F78C700F052D2 /* Build configuration list for PBXNativeTarget "CoordinateAxisChart" */; 137 | buildPhases = ( 138 | 3586946B1E9F78C700F052D2 /* Sources */, 139 | 3586946C1E9F78C700F052D2 /* Frameworks */, 140 | 3586946D1E9F78C700F052D2 /* Resources */, 141 | ); 142 | buildRules = ( 143 | ); 144 | dependencies = ( 145 | ); 146 | name = CoordinateAxisChart; 147 | productName = CoordinateAxisChart; 148 | productReference = 3586946F1E9F78C700F052D2 /* CoordinateAxisChart.app */; 149 | productType = "com.apple.product-type.application"; 150 | }; 151 | 358694821E9F78C700F052D2 /* CoordinateAxisChartTests */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 3586949A1E9F78C700F052D2 /* Build configuration list for PBXNativeTarget "CoordinateAxisChartTests" */; 154 | buildPhases = ( 155 | 3586947F1E9F78C700F052D2 /* Sources */, 156 | 358694801E9F78C700F052D2 /* Frameworks */, 157 | 358694811E9F78C700F052D2 /* Resources */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | 358694851E9F78C700F052D2 /* PBXTargetDependency */, 163 | ); 164 | name = CoordinateAxisChartTests; 165 | productName = CoordinateAxisChartTests; 166 | productReference = 358694831E9F78C700F052D2 /* CoordinateAxisChartTests.xctest */; 167 | productType = "com.apple.product-type.bundle.unit-test"; 168 | }; 169 | 3586948D1E9F78C700F052D2 /* CoordinateAxisChartUITests */ = { 170 | isa = PBXNativeTarget; 171 | buildConfigurationList = 3586949D1E9F78C700F052D2 /* Build configuration list for PBXNativeTarget "CoordinateAxisChartUITests" */; 172 | buildPhases = ( 173 | 3586948A1E9F78C700F052D2 /* Sources */, 174 | 3586948B1E9F78C700F052D2 /* Frameworks */, 175 | 3586948C1E9F78C700F052D2 /* Resources */, 176 | ); 177 | buildRules = ( 178 | ); 179 | dependencies = ( 180 | 358694901E9F78C700F052D2 /* PBXTargetDependency */, 181 | ); 182 | name = CoordinateAxisChartUITests; 183 | productName = CoordinateAxisChartUITests; 184 | productReference = 3586948E1E9F78C700F052D2 /* CoordinateAxisChartUITests.xctest */; 185 | productType = "com.apple.product-type.bundle.ui-testing"; 186 | }; 187 | /* End PBXNativeTarget section */ 188 | 189 | /* Begin PBXProject section */ 190 | 358694671E9F78C700F052D2 /* Project object */ = { 191 | isa = PBXProject; 192 | attributes = { 193 | LastSwiftUpdateCheck = 0820; 194 | LastUpgradeCheck = 0820; 195 | ORGANIZATIONNAME = "朱慧平"; 196 | TargetAttributes = { 197 | 3586946E1E9F78C700F052D2 = { 198 | CreatedOnToolsVersion = 8.2.1; 199 | DevelopmentTeam = 52SDKDKNS7; 200 | ProvisioningStyle = Automatic; 201 | }; 202 | 358694821E9F78C700F052D2 = { 203 | CreatedOnToolsVersion = 8.2.1; 204 | ProvisioningStyle = Automatic; 205 | TestTargetID = 3586946E1E9F78C700F052D2; 206 | }; 207 | 3586948D1E9F78C700F052D2 = { 208 | CreatedOnToolsVersion = 8.2.1; 209 | ProvisioningStyle = Automatic; 210 | TestTargetID = 3586946E1E9F78C700F052D2; 211 | }; 212 | }; 213 | }; 214 | buildConfigurationList = 3586946A1E9F78C700F052D2 /* Build configuration list for PBXProject "CoordinateAxisChart" */; 215 | compatibilityVersion = "Xcode 3.2"; 216 | developmentRegion = English; 217 | hasScannedForEncodings = 0; 218 | knownRegions = ( 219 | en, 220 | Base, 221 | ); 222 | mainGroup = 358694661E9F78C700F052D2; 223 | productRefGroup = 358694701E9F78C700F052D2 /* Products */; 224 | projectDirPath = ""; 225 | projectRoot = ""; 226 | targets = ( 227 | 3586946E1E9F78C700F052D2 /* CoordinateAxisChart */, 228 | 358694821E9F78C700F052D2 /* CoordinateAxisChartTests */, 229 | 3586948D1E9F78C700F052D2 /* CoordinateAxisChartUITests */, 230 | ); 231 | }; 232 | /* End PBXProject section */ 233 | 234 | /* Begin PBXResourcesBuildPhase section */ 235 | 3586946D1E9F78C700F052D2 /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | 3586947D1E9F78C700F052D2 /* LaunchScreen.storyboard in Resources */, 240 | 3586947A1E9F78C700F052D2 /* Assets.xcassets in Resources */, 241 | 358694781E9F78C700F052D2 /* Main.storyboard in Resources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | 358694811E9F78C700F052D2 /* Resources */ = { 246 | isa = PBXResourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | 3586948C1E9F78C700F052D2 /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | }; 259 | /* End PBXResourcesBuildPhase section */ 260 | 261 | /* Begin PBXSourcesBuildPhase section */ 262 | 3586946B1E9F78C700F052D2 /* Sources */ = { 263 | isa = PBXSourcesBuildPhase; 264 | buildActionMask = 2147483647; 265 | files = ( 266 | 355C80D11EA9D8ED001E83AA /* CoordinateAxisChart.swift in Sources */, 267 | 358694751E9F78C700F052D2 /* ViewController.swift in Sources */, 268 | 358694731E9F78C700F052D2 /* AppDelegate.swift in Sources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | 3586947F1E9F78C700F052D2 /* Sources */ = { 273 | isa = PBXSourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | 358694881E9F78C700F052D2 /* CoordinateAxisChartTests.swift in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | 3586948A1E9F78C700F052D2 /* Sources */ = { 281 | isa = PBXSourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | 358694931E9F78C700F052D2 /* CoordinateAxisChartUITests.swift in Sources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | /* End PBXSourcesBuildPhase section */ 289 | 290 | /* Begin PBXTargetDependency section */ 291 | 358694851E9F78C700F052D2 /* PBXTargetDependency */ = { 292 | isa = PBXTargetDependency; 293 | target = 3586946E1E9F78C700F052D2 /* CoordinateAxisChart */; 294 | targetProxy = 358694841E9F78C700F052D2 /* PBXContainerItemProxy */; 295 | }; 296 | 358694901E9F78C700F052D2 /* PBXTargetDependency */ = { 297 | isa = PBXTargetDependency; 298 | target = 3586946E1E9F78C700F052D2 /* CoordinateAxisChart */; 299 | targetProxy = 3586948F1E9F78C700F052D2 /* PBXContainerItemProxy */; 300 | }; 301 | /* End PBXTargetDependency section */ 302 | 303 | /* Begin PBXVariantGroup section */ 304 | 358694761E9F78C700F052D2 /* Main.storyboard */ = { 305 | isa = PBXVariantGroup; 306 | children = ( 307 | 358694771E9F78C700F052D2 /* Base */, 308 | ); 309 | name = Main.storyboard; 310 | sourceTree = ""; 311 | }; 312 | 3586947B1E9F78C700F052D2 /* LaunchScreen.storyboard */ = { 313 | isa = PBXVariantGroup; 314 | children = ( 315 | 3586947C1E9F78C700F052D2 /* Base */, 316 | ); 317 | name = LaunchScreen.storyboard; 318 | sourceTree = ""; 319 | }; 320 | /* End PBXVariantGroup section */ 321 | 322 | /* Begin XCBuildConfiguration section */ 323 | 358694951E9F78C700F052D2 /* Debug */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | ALWAYS_SEARCH_USER_PATHS = NO; 327 | CLANG_ANALYZER_NONNULL = YES; 328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 329 | CLANG_CXX_LIBRARY = "libc++"; 330 | CLANG_ENABLE_MODULES = YES; 331 | CLANG_ENABLE_OBJC_ARC = YES; 332 | CLANG_WARN_BOOL_CONVERSION = YES; 333 | CLANG_WARN_CONSTANT_CONVERSION = YES; 334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 335 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 336 | CLANG_WARN_EMPTY_BODY = YES; 337 | CLANG_WARN_ENUM_CONVERSION = YES; 338 | CLANG_WARN_INFINITE_RECURSION = YES; 339 | CLANG_WARN_INT_CONVERSION = YES; 340 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 341 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 342 | CLANG_WARN_UNREACHABLE_CODE = YES; 343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 344 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 345 | COPY_PHASE_STRIP = NO; 346 | DEBUG_INFORMATION_FORMAT = dwarf; 347 | ENABLE_STRICT_OBJC_MSGSEND = YES; 348 | ENABLE_TESTABILITY = YES; 349 | GCC_C_LANGUAGE_STANDARD = gnu99; 350 | GCC_DYNAMIC_NO_PIC = NO; 351 | GCC_NO_COMMON_BLOCKS = YES; 352 | GCC_OPTIMIZATION_LEVEL = 0; 353 | GCC_PREPROCESSOR_DEFINITIONS = ( 354 | "DEBUG=1", 355 | "$(inherited)", 356 | ); 357 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 358 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 359 | GCC_WARN_UNDECLARED_SELECTOR = YES; 360 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 361 | GCC_WARN_UNUSED_FUNCTION = YES; 362 | GCC_WARN_UNUSED_VARIABLE = YES; 363 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 364 | MTL_ENABLE_DEBUG_INFO = YES; 365 | ONLY_ACTIVE_ARCH = YES; 366 | SDKROOT = iphoneos; 367 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 368 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 369 | }; 370 | name = Debug; 371 | }; 372 | 358694961E9F78C700F052D2 /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ALWAYS_SEARCH_USER_PATHS = NO; 376 | CLANG_ANALYZER_NONNULL = YES; 377 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 378 | CLANG_CXX_LIBRARY = "libc++"; 379 | CLANG_ENABLE_MODULES = YES; 380 | CLANG_ENABLE_OBJC_ARC = YES; 381 | CLANG_WARN_BOOL_CONVERSION = YES; 382 | CLANG_WARN_CONSTANT_CONVERSION = YES; 383 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 384 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 385 | CLANG_WARN_EMPTY_BODY = YES; 386 | CLANG_WARN_ENUM_CONVERSION = YES; 387 | CLANG_WARN_INFINITE_RECURSION = YES; 388 | CLANG_WARN_INT_CONVERSION = YES; 389 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 394 | COPY_PHASE_STRIP = NO; 395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 396 | ENABLE_NS_ASSERTIONS = NO; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_NO_COMMON_BLOCKS = YES; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = iphoneos; 409 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 410 | VALIDATE_PRODUCT = YES; 411 | }; 412 | name = Release; 413 | }; 414 | 358694981E9F78C700F052D2 /* Debug */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 418 | DEVELOPMENT_TEAM = 52SDKDKNS7; 419 | FRAMEWORK_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | "$(PROJECT_DIR)/CoordinateAxisChart", 422 | ); 423 | INFOPLIST_FILE = CoordinateAxisChart/Info.plist; 424 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 425 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 426 | PRODUCT_BUNDLE_IDENTIFIER = shinetechchina.shareModel.CoordinateAxisChart; 427 | PRODUCT_NAME = "$(TARGET_NAME)"; 428 | SWIFT_VERSION = 3.0; 429 | }; 430 | name = Debug; 431 | }; 432 | 358694991E9F78C700F052D2 /* Release */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 436 | DEVELOPMENT_TEAM = 52SDKDKNS7; 437 | FRAMEWORK_SEARCH_PATHS = ( 438 | "$(inherited)", 439 | "$(PROJECT_DIR)/CoordinateAxisChart", 440 | ); 441 | INFOPLIST_FILE = CoordinateAxisChart/Info.plist; 442 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 443 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 444 | PRODUCT_BUNDLE_IDENTIFIER = shinetechchina.shareModel.CoordinateAxisChart; 445 | PRODUCT_NAME = "$(TARGET_NAME)"; 446 | SWIFT_VERSION = 3.0; 447 | }; 448 | name = Release; 449 | }; 450 | 3586949B1E9F78C700F052D2 /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 454 | BUNDLE_LOADER = "$(TEST_HOST)"; 455 | INFOPLIST_FILE = CoordinateAxisChartTests/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 457 | PRODUCT_BUNDLE_IDENTIFIER = shinetechchina.shareModel.CoordinateAxisChartTests; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | SWIFT_VERSION = 3.0; 460 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CoordinateAxisChart.app/CoordinateAxisChart"; 461 | }; 462 | name = Debug; 463 | }; 464 | 3586949C1E9F78C700F052D2 /* Release */ = { 465 | isa = XCBuildConfiguration; 466 | buildSettings = { 467 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 468 | BUNDLE_LOADER = "$(TEST_HOST)"; 469 | INFOPLIST_FILE = CoordinateAxisChartTests/Info.plist; 470 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 471 | PRODUCT_BUNDLE_IDENTIFIER = shinetechchina.shareModel.CoordinateAxisChartTests; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | SWIFT_VERSION = 3.0; 474 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CoordinateAxisChart.app/CoordinateAxisChart"; 475 | }; 476 | name = Release; 477 | }; 478 | 3586949E1E9F78C700F052D2 /* Debug */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 482 | INFOPLIST_FILE = CoordinateAxisChartUITests/Info.plist; 483 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 484 | PRODUCT_BUNDLE_IDENTIFIER = shinetechchina.shareModel.CoordinateAxisChartUITests; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | SWIFT_VERSION = 3.0; 487 | TEST_TARGET_NAME = CoordinateAxisChart; 488 | }; 489 | name = Debug; 490 | }; 491 | 3586949F1E9F78C700F052D2 /* Release */ = { 492 | isa = XCBuildConfiguration; 493 | buildSettings = { 494 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 495 | INFOPLIST_FILE = CoordinateAxisChartUITests/Info.plist; 496 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 497 | PRODUCT_BUNDLE_IDENTIFIER = shinetechchina.shareModel.CoordinateAxisChartUITests; 498 | PRODUCT_NAME = "$(TARGET_NAME)"; 499 | SWIFT_VERSION = 3.0; 500 | TEST_TARGET_NAME = CoordinateAxisChart; 501 | }; 502 | name = Release; 503 | }; 504 | /* End XCBuildConfiguration section */ 505 | 506 | /* Begin XCConfigurationList section */ 507 | 3586946A1E9F78C700F052D2 /* Build configuration list for PBXProject "CoordinateAxisChart" */ = { 508 | isa = XCConfigurationList; 509 | buildConfigurations = ( 510 | 358694951E9F78C700F052D2 /* Debug */, 511 | 358694961E9F78C700F052D2 /* Release */, 512 | ); 513 | defaultConfigurationIsVisible = 0; 514 | defaultConfigurationName = Release; 515 | }; 516 | 358694971E9F78C700F052D2 /* Build configuration list for PBXNativeTarget "CoordinateAxisChart" */ = { 517 | isa = XCConfigurationList; 518 | buildConfigurations = ( 519 | 358694981E9F78C700F052D2 /* Debug */, 520 | 358694991E9F78C700F052D2 /* Release */, 521 | ); 522 | defaultConfigurationIsVisible = 0; 523 | defaultConfigurationName = Release; 524 | }; 525 | 3586949A1E9F78C700F052D2 /* Build configuration list for PBXNativeTarget "CoordinateAxisChartTests" */ = { 526 | isa = XCConfigurationList; 527 | buildConfigurations = ( 528 | 3586949B1E9F78C700F052D2 /* Debug */, 529 | 3586949C1E9F78C700F052D2 /* Release */, 530 | ); 531 | defaultConfigurationIsVisible = 0; 532 | defaultConfigurationName = Release; 533 | }; 534 | 3586949D1E9F78C700F052D2 /* Build configuration list for PBXNativeTarget "CoordinateAxisChartUITests" */ = { 535 | isa = XCConfigurationList; 536 | buildConfigurations = ( 537 | 3586949E1E9F78C700F052D2 /* Debug */, 538 | 3586949F1E9F78C700F052D2 /* Release */, 539 | ); 540 | defaultConfigurationIsVisible = 0; 541 | defaultConfigurationName = Release; 542 | }; 543 | /* End XCConfigurationList section */ 544 | }; 545 | rootObject = 358694671E9F78C700F052D2 /* Project object */; 546 | } 547 | -------------------------------------------------------------------------------- /CoordinateAxisChart.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CoordinateAxisChart.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CoordinateAxisChart.xcodeproj/project.xcworkspace/xcuserdata/zhuhuiping.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrystalMarch/CoordinateAxisChart/9ac36b04614a1538c26e6693e06495e419320b79/CoordinateAxisChart.xcodeproj/project.xcworkspace/xcuserdata/zhuhuiping.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CoordinateAxisChart.xcodeproj/xcuserdata/zhuhuiping.xcuserdatad/xcschemes/CoordinateAxisChart.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /CoordinateAxisChart.xcodeproj/xcuserdata/zhuhuiping.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CoordinateAxisChart.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 3586946E1E9F78C700F052D2 16 | 17 | primary 18 | 19 | 20 | 358694821E9F78C700F052D2 21 | 22 | primary 23 | 24 | 25 | 3586948D1E9F78C700F052D2 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /CoordinateAxisChart/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CoordinateAxisChart 4 | // 5 | // Created by 朱慧平 on 2017/4/13. 6 | // Copyright © 2017年 朱慧平. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // 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. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /CoordinateAxisChart/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /CoordinateAxisChart/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 | 27 | 28 | -------------------------------------------------------------------------------- /CoordinateAxisChart/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 | 26 | 27 | -------------------------------------------------------------------------------- /CoordinateAxisChart/CoordinateAxisChart/CoordinateAxisChart.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartView.swift 3 | // Chart 4 | // 5 | // Created by 朱慧平 on 2017/4/5. 6 | // Copyright © 2017年 朱慧平. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | public enum ChartType { 11 | case point 12 | case line 13 | } 14 | open class CoordinateAxisChart: UIView { 15 | fileprivate let xAxis = UIView() 16 | fileprivate let yAxis = UIView() 17 | fileprivate var width :CGFloat! 18 | fileprivate var height :CGFloat! 19 | fileprivate var pointArray = Array<[CGPoint]>() 20 | fileprivate var chartTypeArray = Array() 21 | fileprivate var lineColorArray = Array() 22 | fileprivate var layerArray = Array() 23 | fileprivate var animationArray = Array() 24 | fileprivate let backgroundView = UIView() 25 | fileprivate let yArrowLayer = CAShapeLayer() 26 | fileprivate let xArrowLayer = CAShapeLayer() 27 | fileprivate var xMargin = CGFloat(14) 28 | fileprivate var yMargin = CGFloat(14) 29 | 30 | public var xMaxValue:Int = 5 { 31 | didSet { 32 | updateLayerFrames() 33 | } 34 | } 35 | 36 | public var yMaxValue:Int = 5 { 37 | didSet { 38 | updateLayerFrames() 39 | } 40 | } 41 | 42 | public var xMinValue:Int = -5 { 43 | didSet { 44 | updateLayerFrames() 45 | } 46 | } 47 | 48 | public var yMinValue:Int = -5 { 49 | didSet { 50 | updateLayerFrames() 51 | } 52 | } 53 | 54 | public var axisColor: UIColor = .black { 55 | didSet { 56 | updateLayerFrames() 57 | } 58 | 59 | } 60 | 61 | public var animationTime: Float = 1 { 62 | didSet { 63 | updateLayerFrames() 64 | } 65 | } 66 | 67 | override init(frame: CGRect) { 68 | super.init(frame: frame) 69 | } 70 | override open var frame: CGRect { 71 | didSet { 72 | updateLayerFrames() 73 | } 74 | } 75 | 76 | fileprivate func updateLayerFrames() { 77 | self.layer.masksToBounds = true 78 | 79 | xMargin = self.frame.width/CGFloat(2+xMaxValue-xMinValue) 80 | yMargin = self.frame.width/CGFloat(2+yMaxValue-yMinValue) 81 | width = self.frame.width - 2*xMargin 82 | height = self.frame.height - 2*yMargin 83 | if width > 0 { 84 | backgroundView.removeFromSuperview() 85 | for subview in backgroundView.subviews { 86 | subview.removeFromSuperview() 87 | } 88 | backgroundView.layer.removeFromSuperlayer() 89 | backgroundView.frame = self.bounds 90 | self.addSubview(backgroundView) 91 | self.addAxis() 92 | self.addArrowForAxis() 93 | self.reSetPointData() 94 | } 95 | } 96 | 97 | fileprivate func addAxis() { 98 | xAxis.frame = CGRect(x:0,y:CGFloat(yMaxValue + 1)*yMargin,width:self.frame.width,height:0.5) 99 | yAxis.frame = CGRect(x:CGFloat(1-xMinValue)*xMargin,y:0,width:0.5,height:self.frame.height) 100 | xAxis.backgroundColor = axisColor 101 | yAxis.backgroundColor = axisColor 102 | backgroundView.addSubview(xAxis) 103 | backgroundView.addSubview(yAxis) 104 | for xIndex in xMinValue...xMaxValue{ 105 | let xLine = UIView() 106 | xLine.backgroundColor = axisColor 107 | xLine.frame = CGRect(x:CGFloat(xIndex-xMinValue+1)*xMargin,y:(CGFloat(yMaxValue + 1)-0.25)*yMargin,width:0.5,height:yMargin/2) 108 | backgroundView.addSubview(xLine) 109 | let xLabel = UILabel() 110 | xLabel.textColor = axisColor 111 | xLabel.font = UIFont.systemFont(ofSize: 10) 112 | xLabel.text = "\(xIndex)" 113 | if xIndex != 0 { 114 | xLabel.textAlignment = .center 115 | }else{ 116 | xLabel.textAlignment = .right 117 | } 118 | xLabel.frame = CGRect(x:(CGFloat(xIndex-xMinValue+1)-0.5)*xMargin,y:(CGFloat(yMaxValue + 1)+0.25)*yMargin,width:xMargin,height:yMargin/2) 119 | backgroundView.addSubview(xLabel) 120 | } 121 | 122 | for yIndex in yMinValue...yMaxValue { 123 | 124 | let yLine = UIView() 125 | yLine.backgroundColor = axisColor 126 | yLine.frame = CGRect(x:(CGFloat(1-xMinValue)-0.25)*xMargin,y:CGFloat(yMaxValue-yIndex+1)*yMargin,width:xMargin/2,height:0.5) 127 | backgroundView.addSubview(yLine) 128 | 129 | let yLabel = UILabel() 130 | yLabel.textColor = axisColor 131 | yLabel.frame = CGRect(x:(CGFloat(1-xMinValue)+0.25)*xMargin,y:(CGFloat(yMaxValue-yIndex+1)-0.5)*yMargin,width:xMargin,height:yMargin) 132 | yLabel.font = UIFont.systemFont(ofSize: 10) 133 | yLabel.textAlignment = .center 134 | if yIndex != 0 { 135 | yLabel.text = "\(yIndex)" 136 | } 137 | backgroundView.addSubview(yLabel) 138 | } 139 | } 140 | fileprivate func addArrowForAxis() { 141 | xArrowLayer.removeFromSuperlayer() 142 | yArrowLayer.removeFromSuperlayer() 143 | let path = UIBezierPath() 144 | path.move(to: CGPoint(x:CGFloat(1-xMinValue)*xMargin-5,y:5)) 145 | path.addLine(to: CGPoint(x:CGFloat(1-xMinValue)*xMargin,y:0)) 146 | path.addLine(to: CGPoint(x:CGFloat(1-xMinValue)*xMargin+5,y:5)) 147 | yArrowLayer.path = path.cgPath 148 | yArrowLayer.fillColor = UIColor.clear.cgColor 149 | yArrowLayer.strokeColor = axisColor.cgColor 150 | yArrowLayer.lineWidth = 0.5 151 | backgroundView.layer.addSublayer(yArrowLayer) 152 | path.move(to: CGPoint(x:backgroundView.frame.size.width-5,y:CGFloat(yMaxValue + 1)*yMargin-5)) 153 | path.addLine(to: CGPoint(x:backgroundView.frame.size.width,y:CGFloat(yMaxValue + 1)*yMargin)) 154 | path.addLine(to: CGPoint(x:backgroundView.frame.size.width-5,y:CGFloat(yMaxValue + 1)*yMargin+5)) 155 | xArrowLayer.path = path.cgPath 156 | xArrowLayer.fillColor = UIColor.clear.cgColor 157 | xArrowLayer.strokeColor = axisColor.cgColor 158 | xArrowLayer.lineWidth = 0.5 159 | backgroundView.layer.addSublayer(xArrowLayer) 160 | 161 | } 162 | public func clear(){ 163 | for subLayer in layerArray { 164 | subLayer.removeFromSuperlayer() 165 | } 166 | layerArray.removeAll() 167 | } 168 | public func refresh(){ 169 | self.reSetPointData() 170 | } 171 | public func setPointData(pointData:[CGPoint],chartType:ChartType,lineOrPointColor:UIColor,animation:Bool) { 172 | pointArray.append(pointData) 173 | lineColorArray.append(lineOrPointColor) 174 | chartTypeArray.append(chartType) 175 | animationArray.append(animation) 176 | if chartType == .line { 177 | self.addLine(pointData: pointData,lineColor: lineOrPointColor,animation: animation) 178 | }else{ 179 | self.addPoint(pointData: pointData,pointColor: lineOrPointColor) 180 | } 181 | } 182 | fileprivate func reSetPointData() { 183 | for subLayer in layerArray { 184 | subLayer.removeFromSuperlayer() 185 | } 186 | layerArray.removeAll() 187 | for index in 0.. 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 38 | 39 | -------------------------------------------------------------------------------- /CoordinateAxisChart/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CoordinateAxisChart 4 | // 5 | // Created by 朱慧平 on 2017/4/13. 6 | // Copyright © 2017年 朱慧平. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | let chartView = CoordinateAxisChart() 13 | 14 | final class RefreshButton: UIButton { 15 | convenience init(viewController: ViewController) { 16 | self.init() 17 | frame = CGRect(x:30,y:40,width:120,height:30) 18 | setTitle("refresh", for: .normal) 19 | addTarget(viewController, action: #selector(viewController.refreshButonClick(sender:)), for: .touchUpInside) 20 | setTitleColor(.gray, for: .normal) 21 | setTitleColor(.red, for: .highlighted) 22 | layer.borderWidth = 1 23 | layer.borderColor = UIColor.gray.cgColor 24 | } 25 | } 26 | 27 | final class ClearButton: UIButton { 28 | convenience init(viewController: ViewController) { 29 | self.init() 30 | frame = CGRect(x: viewController.view.frame.size.width-150, y: 40, width: 120, height: 30) 31 | setTitle("clear", for: .normal) 32 | addTarget(viewController, action: #selector(viewController.clearButtonClick(sender:)), for: .touchUpInside) 33 | setTitleColor(.gray, for: .normal) 34 | setTitleColor(.red, for: .highlighted) 35 | layer.borderWidth = 1 36 | layer.borderColor = UIColor.gray.cgColor 37 | } 38 | } 39 | 40 | final class ChangeAxisValueButton: UIButton { 41 | convenience init(viewController: ViewController) { 42 | self.init() 43 | frame = CGRect(x:30,y:80,width: viewController.view.frame.size.width - 60,height:30) 44 | setTitle("change coordinate axis value", for: .normal) 45 | addTarget(viewController, action: #selector(viewController.changeAxisValueButtonClick(sender:)), for: .touchUpInside) 46 | setTitleColor(.gray, for: .normal) 47 | setTitleColor(.red, for: .highlighted) 48 | layer.borderWidth = 1 49 | layer.borderColor = UIColor.gray.cgColor 50 | } 51 | } 52 | 53 | final class ChangeAxisColorButton: UIButton { 54 | convenience init(viewController: ViewController) { 55 | self.init() 56 | frame = CGRect(x:30,y:120,width: viewController.view.frame.size.width - 60,height:30) 57 | setTitle("change coordinate axis color", for: .normal) 58 | addTarget(viewController, action: #selector(viewController.changeAxisColorButtonClick(sender:)), for: .touchUpInside) 59 | setTitleColor(.gray, for: .normal) 60 | setTitleColor(.red, for: .highlighted) 61 | layer.borderWidth = 1 62 | layer.borderColor = UIColor.gray.cgColor 63 | } 64 | } 65 | override func viewDidLoad() { 66 | super.viewDidLoad() 67 | // Do any additional setup after loading the view, typically from a nib. 68 | let refreshButton = RefreshButton(viewController: self) 69 | self.view.addSubview(refreshButton) 70 | 71 | let clearButton = ClearButton(viewController: self) 72 | self.view.addSubview(clearButton) 73 | 74 | let changeAxisValueButton = ChangeAxisValueButton(viewController: self) 75 | self.view.addSubview(changeAxisValueButton) 76 | 77 | let changeAxisColorButton = ChangeAxisColorButton(viewController: self) 78 | self.view.addSubview(changeAxisColorButton) 79 | 80 | chartView.frame = CGRect(x:50,y:170,width:220,height:220) 81 | let pointData: [CGPoint] = (-40...70).map { 82 | let xAxis = CGFloat($0)/10 83 | let yAxis = sin (xAxis) 84 | /* 85 | yAxis = xAxis - 3 linear function(一次函数) 86 | yAxis = pow(xAxis, 2) - 1 power function(幂函数) 87 | yAxis = pow(2, xAxis) exponential function(指数函数) 88 | yAxis = log (xAxis) logarithmic function, xAxis should be greater than zero(对数函数, 此时应该设置xAxis的值大于0) 89 | yAxis = sin (xAxis) circular function(三角函数), 90 | */ 91 | return CGPoint(x: xAxis, y: yAxis) 92 | } 93 | 94 | chartView.setPointData(pointData: pointData, chartType: .line, lineOrPointColor: .red, animation: true) 95 | // chartView.setPointData(pointData: [CGPoint(x:-2,y:1)], chartType: .point,lineOrPointColor:UIColor .black,animation: false) 96 | chartView.xMaxValue = 7 97 | chartView.animationTime = 2 98 | chartView.axisColor = .gray 99 | chartView.xMinValue = -4 100 | chartView.yMaxValue = 3 101 | chartView.yMinValue = -3 102 | self.view.addSubview(chartView) 103 | } 104 | func refreshButonClick(sender:UIButton) { 105 | chartView.refresh() 106 | } 107 | 108 | func clearButtonClick(sender:UIButton) { 109 | chartView.clear() 110 | } 111 | 112 | func changeAxisColorButtonClick(sender: UIButton) { 113 | chartView.axisColor = .random() 114 | } 115 | 116 | func changeAxisValueButtonClick(sender:UIButton) { 117 | chartView.xMaxValue = Int(arc4random()%10) 118 | chartView.xMinValue = -Int(arc4random()%10) 119 | chartView.yMaxValue = Int(arc4random()%10) 120 | chartView.yMinValue = -Int(arc4random()%10) 121 | } 122 | 123 | override func didReceiveMemoryWarning() { 124 | super.didReceiveMemoryWarning() 125 | // Dispose of any resources that can be recreated. 126 | } 127 | } 128 | 129 | extension UIColor { 130 | static func random() -> UIColor { 131 | let red = CGFloat(arc4random()%256)/255.0 132 | let green = CGFloat(arc4random()%256)/255.0 133 | let blue = CGFloat(arc4random()%256)/255.0 134 | return UIColor(red: red, green: green, blue: blue, alpha: 1.0) 135 | } 136 | } 137 | 138 | -------------------------------------------------------------------------------- /CoordinateAxisChartDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrystalMarch/CoordinateAxisChart/9ac36b04614a1538c26e6693e06495e419320b79/CoordinateAxisChartDemo.gif -------------------------------------------------------------------------------- /CoordinateAxisChartTests/CoordinateAxisChartTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoordinateAxisChartTests.swift 3 | // CoordinateAxisChartTests 4 | // 5 | // Created by 朱慧平 on 2017/4/13. 6 | // Copyright © 2017年 朱慧平. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import CoordinateAxisChart 11 | 12 | class CoordinateAxisChartTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CoordinateAxisChartTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /CoordinateAxisChartUITests/CoordinateAxisChartUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoordinateAxisChartUITests.swift 3 | // CoordinateAxisChartUITests 4 | // 5 | // Created by 朱慧平 on 2017/4/13. 6 | // Copyright © 2017年 朱慧平. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CoordinateAxisChartUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CoordinateAxisChartUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoordinateAxisChart 2 | ## Drawing graphs of point, linear function, power function, exponential function, logarithmic function, circular function, etc in a coordinate. (实现了在坐标系中画点,一次函数,幂函数,指数函数,对数函数,三角函数等) 3 | 4 | ### for instance: 5 | * linear function(一次函数): yAxis = xAxis - 3 6 | * power function(幂函数): yAxis = pow(xAxis, 2) 7 | * exponential function(指数函数): yAxis = pow(2, xAxis) 8 | * logarithmic function, xAxis should be greater than zero(对数函数, 此时应该设置axis的值大于0): yAxis = log (xAxis) 9 | * circular function(三角函数), like sin, cos, tan: yAxis = sin (xAxis) 10 | 11 | ### Android version entrance 12 | > [CoordinateAxisChart for Android](https://github.com/KiBa1215/CoordinateAxisChart) 13 | 14 | ### Effect picture 15 | ![alt text](https://github.com/CrystalMarch/CoordinateAxisChart/blob/master/CoordinateAxisChartDemo.gif) 16 | ![alt text](https://github.com/CrystalMarch/CoordinateAxisChart/blob/master/charttwo.png) 17 | ![alt text](https://github.com/CrystalMarch/CoordinateAxisChart/blob/master/chart.png) 18 | 19 | ## Installation 20 | 21 | ### CocoaPods 22 | 23 | Add to your Podfile: 24 | 25 | Swift: 26 | ```ruby 27 | use_frameworks! 28 | pod 'CoordinateAxisChart', '~> 1.0.1' 29 | ``` 30 | Note: To use Swift 3.x / master, you need Xcode 8+ 31 | 32 | To use master directly (it's usually stable): 33 | ```ruby 34 | pod 'CoordinateAxisChart', :git => 'https://github.com/CrystalMarch/CoordinateAxisChart.git' 35 | ``` 36 | 37 | And then: 38 | ```ruby 39 | pod install 40 | ``` 41 | 42 | Import the framework in your code: 43 | ```swift 44 | import CoordinateAxisChart 45 | ``` 46 | 47 | ## Quick start 48 | ```swift 49 | let chartView = CoordinateAxisChart() 50 | chartView.frame = CGRect(x:50,y:50,width:220,height:220) 51 | var pointData: [CGPoint] = [] 52 | for i in -40...70 { 53 | let xAxis = CGFloat(i)/10 54 | let yAxis = sin (xAxis) 55 | pointData.append(CGPoint(x:xAxis,y:yAxis)) 56 | } 57 | chartView.setPointData(pointData: pointData, chartType: .line,lineOrPointColor:UIColor .red,animation: true) 58 | chartView.xMaxValue = 7 59 | chartView.animationTime = 2 60 | chartView.axisColor = UIColor.gray 61 | chartView.xMinValue = -4 62 | chartView.yMaxValue = 3 63 | chartView.yMinValue = -3 64 |        self.view.addSubview(chartView) 65 | ``` 66 | ```swift 67 | func refreshButonClick(sender:UIButton) { 68 | chartView.refresh() 69 | } 70 | ``` 71 | ```swift 72 | func clearButtonClick(sender:UIButton) { 73 | chartView.clear() 74 | } 75 | ``` 76 | ```swift 77 | func changeAxisColorButtonClick(sender: UIButton) { 78 | let red = CGFloat(arc4random()%256)/255.0 79 | let green = CGFloat(arc4random()%256)/255.0 80 | let blue = CGFloat(arc4random()%256)/255.0 81 | chartView.axisColor = UIColor(red: red, green: green, blue: blue, alpha: 1.0) 82 | } 83 | ``` 84 | ```swift 85 | func changeAxisValueButtonClick(sender:UIButton) { 86 | chartView.xMaxValue = Int(arc4random()%10) 87 | chartView.xMinValue = -Int(arc4random()%10) 88 | chartView.yMaxValue = Int(arc4random()%10) 89 | chartView.yMinValue = -Int(arc4random()%10) 90 | } 91 | ``` 92 | ### Properties: 93 | #### xMaxValue: 94 | * set the max value of x axis(设置x轴的最大值) 95 | #### xMinValue: 96 | * set the min value of x axis(设置x轴的最小值) 97 | #### yMaxValue: 98 | * set the max value of y axis(设置y轴的最大值) 99 | #### yMinValue: 100 | * set the min value of y axis(设置y轴的最小值) 101 | #### axisColor: 102 | * set the color of the axis(设置坐标轴的颜色) 103 | #### animationTime: 104 | * set the animation time of draw line(设置画函数线条的动画时间) 105 | 106 | ### Function: 107 | #### setPointData(pointData:[CGPoint],chartType:ChartType,lineOrPointColor:UIColor,animation:Bool) 108 | * pointDate: set the data for chart 109 | * chartType: set the chart type (line or point) 110 | * lineOrPointColor: set the line or point color 111 | * animation: set whether animation is needed 112 | #### refresh() 113 | #### clear() 114 | 115 | 116 | -------------------------------------------------------------------------------- /chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrystalMarch/CoordinateAxisChart/9ac36b04614a1538c26e6693e06495e419320b79/chart.png -------------------------------------------------------------------------------- /charttwo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrystalMarch/CoordinateAxisChart/9ac36b04614a1538c26e6693e06495e419320b79/charttwo.png --------------------------------------------------------------------------------