├── .gitignore ├── LICENSE.md ├── MSBBarChart.podspec ├── MSBBarChart.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── MSBBarChart.xcscheme │ └── Sample.xcscheme ├── MSBBarChart ├── Info.plist ├── MSBBarChart.h └── Sources │ └── MSBBarChartView.swift ├── Package.swift ├── README.md └── Sample ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── SceneDelegate.swift └── ViewController.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | .build/ 7 | build/ 8 | DerivedData/ 9 | archive.xcarchive 10 | Booklog.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata/ 22 | 23 | ## Other 24 | *.moved-aside 25 | *.xcuserstate 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | fastlane/report.xml 38 | fastlane/Preview.html 39 | fastlane/screenshots 40 | fastlane/test_output 41 | 42 | # Ruby gems 43 | vendor 44 | .bundle 45 | 46 | # Cocoapods 47 | Pods/* 48 | 49 | # NPM 50 | node_modules 51 | npm-debug.log 52 | 53 | .DS_Store 54 | .idea/ 55 | !.github 56 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License Copyright © 2020 Naoto Takahashi naoto0101@gmail.com All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /MSBBarChart.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint MetaRod.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 10 | spec.name = "MSBBarChart" 11 | spec.version = "1.1.2" 12 | spec.summary = "MSBBarChart is an easy to use bar chart library for iOS" 13 | spec.homepage = "https://github.com/misyobun/MSBBarChart" 14 | spec.screenshots = "https://user-images.githubusercontent.com/509448/73722607-38024600-476a-11ea-8806-cc4a9245ffd8.gif" 15 | spec.license = "MIT" 16 | spec.author = "misyobun" 17 | spec.social_media_url = "https://twitter.com/misyobun" 18 | spec.platform = :ios 19 | spec.requires_arc = true 20 | spec.swift_versions = ['5.0'] 21 | spec.source = { :git => "https://github.com/misyobun/MSBBarChart.git", :tag => spec.version.to_s } 22 | spec.source_files = "MSBBarChart/Sources/**/*" 23 | spec.ios.deployment_target = '13.0' 24 | end 25 | -------------------------------------------------------------------------------- /MSBBarChart.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7470991623E830BB0003B660 /* MSBBarChart.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74F3A54323DEC3DD004A020D /* MSBBarChart.framework */; }; 11 | 7470991A23E94CCC0003B660 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7470991923E94CCC0003B660 /* SceneDelegate.swift */; }; 12 | 74F3A54823DEC3DD004A020D /* MSBBarChart.h in Headers */ = {isa = PBXBuildFile; fileRef = 74F3A54623DEC3DD004A020D /* MSBBarChart.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 74F3A54F23DEC427004A020D /* MSBBarChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F3A54E23DEC427004A020D /* MSBBarChartView.swift */; }; 14 | 74F3A56F23DECE96004A020D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F3A56E23DECE96004A020D /* AppDelegate.swift */; }; 15 | 74F3A57323DECE96004A020D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F3A57223DECE96004A020D /* ViewController.swift */; }; 16 | 74F3A57623DECE96004A020D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74F3A57423DECE96004A020D /* Main.storyboard */; }; 17 | 74F3A57823DECE97004A020D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 74F3A57723DECE97004A020D /* Assets.xcassets */; }; 18 | 74F3A57B23DECE97004A020D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74F3A57923DECE97004A020D /* LaunchScreen.storyboard */; }; 19 | 74F3A58223DEDDCE004A020D /* MSBBarChart.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 74F3A54323DEC3DD004A020D /* MSBBarChart.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 74F3A58323DEDDCE004A020D /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 74F3A53A23DEC3DD004A020D /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 74F3A54223DEC3DD004A020D; 28 | remoteInfo = MSBBarChart; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXCopyFilesBuildPhase section */ 33 | 74F3A58523DEDDCE004A020D /* Embed Frameworks */ = { 34 | isa = PBXCopyFilesBuildPhase; 35 | buildActionMask = 2147483647; 36 | dstPath = ""; 37 | dstSubfolderSpec = 10; 38 | files = ( 39 | 74F3A58223DEDDCE004A020D /* MSBBarChart.framework in Embed Frameworks */, 40 | ); 41 | name = "Embed Frameworks"; 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXCopyFilesBuildPhase section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 7470991923E94CCC0003B660 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 48 | 74F3A54323DEC3DD004A020D /* MSBBarChart.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MSBBarChart.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 74F3A54623DEC3DD004A020D /* MSBBarChart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSBBarChart.h; sourceTree = ""; }; 50 | 74F3A54723DEC3DD004A020D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 74F3A54E23DEC427004A020D /* MSBBarChartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MSBBarChartView.swift; path = Sources/MSBBarChartView.swift; sourceTree = ""; }; 52 | 74F3A56C23DECE96004A020D /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 74F3A56E23DECE96004A020D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 54 | 74F3A57223DECE96004A020D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 55 | 74F3A57523DECE96004A020D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 56 | 74F3A57723DECE97004A020D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 57 | 74F3A57A23DECE97004A020D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 58 | 74F3A57C23DECE97004A020D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | 74F3A54023DEC3DD004A020D /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | 74F3A56923DECE96004A020D /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 7470991623E830BB0003B660 /* MSBBarChart.framework in Frameworks */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXFrameworksBuildPhase section */ 78 | 79 | /* Begin PBXGroup section */ 80 | 74F3A53923DEC3DD004A020D = { 81 | isa = PBXGroup; 82 | children = ( 83 | 74F3A54523DEC3DD004A020D /* MSBBarChart */, 84 | 74F3A56D23DECE96004A020D /* Sample */, 85 | 74F3A54423DEC3DD004A020D /* Products */, 86 | 74F3A58023DEDDCE004A020D /* Frameworks */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | 74F3A54423DEC3DD004A020D /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 74F3A54323DEC3DD004A020D /* MSBBarChart.framework */, 94 | 74F3A56C23DECE96004A020D /* Sample.app */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 74F3A54523DEC3DD004A020D /* MSBBarChart */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 74F3A54623DEC3DD004A020D /* MSBBarChart.h */, 103 | 74F3A54723DEC3DD004A020D /* Info.plist */, 104 | 74F3A54E23DEC427004A020D /* MSBBarChartView.swift */, 105 | ); 106 | path = MSBBarChart; 107 | sourceTree = ""; 108 | }; 109 | 74F3A56D23DECE96004A020D /* Sample */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 74F3A56E23DECE96004A020D /* AppDelegate.swift */, 113 | 7470991923E94CCC0003B660 /* SceneDelegate.swift */, 114 | 74F3A57223DECE96004A020D /* ViewController.swift */, 115 | 74F3A57423DECE96004A020D /* Main.storyboard */, 116 | 74F3A57723DECE97004A020D /* Assets.xcassets */, 117 | 74F3A57923DECE97004A020D /* LaunchScreen.storyboard */, 118 | 74F3A57C23DECE97004A020D /* Info.plist */, 119 | ); 120 | path = Sample; 121 | sourceTree = ""; 122 | }; 123 | 74F3A58023DEDDCE004A020D /* Frameworks */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | ); 127 | name = Frameworks; 128 | sourceTree = ""; 129 | }; 130 | /* End PBXGroup section */ 131 | 132 | /* Begin PBXHeadersBuildPhase section */ 133 | 74F3A53E23DEC3DD004A020D /* Headers */ = { 134 | isa = PBXHeadersBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 74F3A54823DEC3DD004A020D /* MSBBarChart.h in Headers */, 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | /* End PBXHeadersBuildPhase section */ 142 | 143 | /* Begin PBXNativeTarget section */ 144 | 74F3A54223DEC3DD004A020D /* MSBBarChart */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 74F3A54B23DEC3DD004A020D /* Build configuration list for PBXNativeTarget "MSBBarChart" */; 147 | buildPhases = ( 148 | 74F3A53E23DEC3DD004A020D /* Headers */, 149 | 74F3A53F23DEC3DD004A020D /* Sources */, 150 | 74F3A54023DEC3DD004A020D /* Frameworks */, 151 | 74F3A54123DEC3DD004A020D /* Resources */, 152 | ); 153 | buildRules = ( 154 | ); 155 | dependencies = ( 156 | ); 157 | name = MSBBarChart; 158 | productName = MSBBarChart; 159 | productReference = 74F3A54323DEC3DD004A020D /* MSBBarChart.framework */; 160 | productType = "com.apple.product-type.framework"; 161 | }; 162 | 74F3A56B23DECE96004A020D /* Sample */ = { 163 | isa = PBXNativeTarget; 164 | buildConfigurationList = 74F3A57D23DECE97004A020D /* Build configuration list for PBXNativeTarget "Sample" */; 165 | buildPhases = ( 166 | 74F3A56823DECE96004A020D /* Sources */, 167 | 74F3A56923DECE96004A020D /* Frameworks */, 168 | 74F3A56A23DECE96004A020D /* Resources */, 169 | 74F3A58523DEDDCE004A020D /* Embed Frameworks */, 170 | ); 171 | buildRules = ( 172 | ); 173 | dependencies = ( 174 | 74F3A58423DEDDCE004A020D /* PBXTargetDependency */, 175 | ); 176 | name = Sample; 177 | productName = Sample; 178 | productReference = 74F3A56C23DECE96004A020D /* Sample.app */; 179 | productType = "com.apple.product-type.application"; 180 | }; 181 | /* End PBXNativeTarget section */ 182 | 183 | /* Begin PBXProject section */ 184 | 74F3A53A23DEC3DD004A020D /* Project object */ = { 185 | isa = PBXProject; 186 | attributes = { 187 | LastSwiftUpdateCheck = 1130; 188 | LastUpgradeCheck = 1130; 189 | ORGANIZATIONNAME = msb; 190 | TargetAttributes = { 191 | 74F3A54223DEC3DD004A020D = { 192 | CreatedOnToolsVersion = 11.3.1; 193 | LastSwiftMigration = 1130; 194 | }; 195 | 74F3A56B23DECE96004A020D = { 196 | CreatedOnToolsVersion = 11.3.1; 197 | }; 198 | }; 199 | }; 200 | buildConfigurationList = 74F3A53D23DEC3DD004A020D /* Build configuration list for PBXProject "MSBBarChart" */; 201 | compatibilityVersion = "Xcode 9.3"; 202 | developmentRegion = en; 203 | hasScannedForEncodings = 0; 204 | knownRegions = ( 205 | en, 206 | Base, 207 | ); 208 | mainGroup = 74F3A53923DEC3DD004A020D; 209 | productRefGroup = 74F3A54423DEC3DD004A020D /* Products */; 210 | projectDirPath = ""; 211 | projectRoot = ""; 212 | targets = ( 213 | 74F3A54223DEC3DD004A020D /* MSBBarChart */, 214 | 74F3A56B23DECE96004A020D /* Sample */, 215 | ); 216 | }; 217 | /* End PBXProject section */ 218 | 219 | /* Begin PBXResourcesBuildPhase section */ 220 | 74F3A54123DEC3DD004A020D /* Resources */ = { 221 | isa = PBXResourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | 74F3A56A23DECE96004A020D /* Resources */ = { 228 | isa = PBXResourcesBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | 74F3A57B23DECE97004A020D /* LaunchScreen.storyboard in Resources */, 232 | 74F3A57823DECE97004A020D /* Assets.xcassets in Resources */, 233 | 74F3A57623DECE96004A020D /* Main.storyboard in Resources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXResourcesBuildPhase section */ 238 | 239 | /* Begin PBXSourcesBuildPhase section */ 240 | 74F3A53F23DEC3DD004A020D /* Sources */ = { 241 | isa = PBXSourcesBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | 74F3A54F23DEC427004A020D /* MSBBarChartView.swift in Sources */, 245 | ); 246 | runOnlyForDeploymentPostprocessing = 0; 247 | }; 248 | 74F3A56823DECE96004A020D /* Sources */ = { 249 | isa = PBXSourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | 74F3A57323DECE96004A020D /* ViewController.swift in Sources */, 253 | 74F3A56F23DECE96004A020D /* AppDelegate.swift in Sources */, 254 | 7470991A23E94CCC0003B660 /* SceneDelegate.swift in Sources */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | /* End PBXSourcesBuildPhase section */ 259 | 260 | /* Begin PBXTargetDependency section */ 261 | 74F3A58423DEDDCE004A020D /* PBXTargetDependency */ = { 262 | isa = PBXTargetDependency; 263 | target = 74F3A54223DEC3DD004A020D /* MSBBarChart */; 264 | targetProxy = 74F3A58323DEDDCE004A020D /* PBXContainerItemProxy */; 265 | }; 266 | /* End PBXTargetDependency section */ 267 | 268 | /* Begin PBXVariantGroup section */ 269 | 74F3A57423DECE96004A020D /* Main.storyboard */ = { 270 | isa = PBXVariantGroup; 271 | children = ( 272 | 74F3A57523DECE96004A020D /* Base */, 273 | ); 274 | name = Main.storyboard; 275 | sourceTree = ""; 276 | }; 277 | 74F3A57923DECE97004A020D /* LaunchScreen.storyboard */ = { 278 | isa = PBXVariantGroup; 279 | children = ( 280 | 74F3A57A23DECE97004A020D /* Base */, 281 | ); 282 | name = LaunchScreen.storyboard; 283 | sourceTree = ""; 284 | }; 285 | /* End PBXVariantGroup section */ 286 | 287 | /* Begin XCBuildConfiguration section */ 288 | 74F3A54923DEC3DD004A020D /* Debug */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ALWAYS_SEARCH_USER_PATHS = NO; 292 | CLANG_ANALYZER_NONNULL = YES; 293 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 295 | CLANG_CXX_LIBRARY = "libc++"; 296 | CLANG_ENABLE_MODULES = YES; 297 | CLANG_ENABLE_OBJC_ARC = YES; 298 | CLANG_ENABLE_OBJC_WEAK = YES; 299 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 300 | CLANG_WARN_BOOL_CONVERSION = YES; 301 | CLANG_WARN_COMMA = YES; 302 | CLANG_WARN_CONSTANT_CONVERSION = YES; 303 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 304 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 305 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 306 | CLANG_WARN_EMPTY_BODY = YES; 307 | CLANG_WARN_ENUM_CONVERSION = YES; 308 | CLANG_WARN_INFINITE_RECURSION = YES; 309 | CLANG_WARN_INT_CONVERSION = YES; 310 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 311 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 312 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 313 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 314 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 315 | CLANG_WARN_STRICT_PROTOTYPES = YES; 316 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 317 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 318 | CLANG_WARN_UNREACHABLE_CODE = YES; 319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 320 | COPY_PHASE_STRIP = NO; 321 | CURRENT_PROJECT_VERSION = 1; 322 | DEBUG_INFORMATION_FORMAT = dwarf; 323 | ENABLE_STRICT_OBJC_MSGSEND = YES; 324 | ENABLE_TESTABILITY = YES; 325 | GCC_C_LANGUAGE_STANDARD = gnu11; 326 | GCC_DYNAMIC_NO_PIC = NO; 327 | GCC_NO_COMMON_BLOCKS = YES; 328 | GCC_OPTIMIZATION_LEVEL = 0; 329 | GCC_PREPROCESSOR_DEFINITIONS = ( 330 | "DEBUG=1", 331 | "$(inherited)", 332 | ); 333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 335 | GCC_WARN_UNDECLARED_SELECTOR = YES; 336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 337 | GCC_WARN_UNUSED_FUNCTION = YES; 338 | GCC_WARN_UNUSED_VARIABLE = YES; 339 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 340 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 341 | MTL_FAST_MATH = YES; 342 | ONLY_ACTIVE_ARCH = YES; 343 | SDKROOT = iphoneos; 344 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 345 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 346 | VERSIONING_SYSTEM = "apple-generic"; 347 | VERSION_INFO_PREFIX = ""; 348 | }; 349 | name = Debug; 350 | }; 351 | 74F3A54A23DEC3DD004A020D /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ALWAYS_SEARCH_USER_PATHS = NO; 355 | CLANG_ANALYZER_NONNULL = YES; 356 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 357 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 358 | CLANG_CXX_LIBRARY = "libc++"; 359 | CLANG_ENABLE_MODULES = YES; 360 | CLANG_ENABLE_OBJC_ARC = YES; 361 | CLANG_ENABLE_OBJC_WEAK = YES; 362 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 363 | CLANG_WARN_BOOL_CONVERSION = YES; 364 | CLANG_WARN_COMMA = YES; 365 | CLANG_WARN_CONSTANT_CONVERSION = YES; 366 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 367 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 368 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 369 | CLANG_WARN_EMPTY_BODY = YES; 370 | CLANG_WARN_ENUM_CONVERSION = YES; 371 | CLANG_WARN_INFINITE_RECURSION = YES; 372 | CLANG_WARN_INT_CONVERSION = YES; 373 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 374 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 375 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 376 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 377 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 378 | CLANG_WARN_STRICT_PROTOTYPES = YES; 379 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 380 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 381 | CLANG_WARN_UNREACHABLE_CODE = YES; 382 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 383 | COPY_PHASE_STRIP = NO; 384 | CURRENT_PROJECT_VERSION = 1; 385 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 386 | ENABLE_NS_ASSERTIONS = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu11; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 397 | MTL_ENABLE_DEBUG_INFO = NO; 398 | MTL_FAST_MATH = YES; 399 | SDKROOT = iphoneos; 400 | SWIFT_COMPILATION_MODE = wholemodule; 401 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 402 | VALIDATE_PRODUCT = YES; 403 | VERSIONING_SYSTEM = "apple-generic"; 404 | VERSION_INFO_PREFIX = ""; 405 | }; 406 | name = Release; 407 | }; 408 | 74F3A54C23DEC3DD004A020D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | CLANG_ENABLE_MODULES = YES; 412 | CODE_SIGN_STYLE = Automatic; 413 | DEFINES_MODULE = YES; 414 | DEVELOPMENT_TEAM = 974NSG8G39; 415 | DYLIB_COMPATIBILITY_VERSION = 1; 416 | DYLIB_CURRENT_VERSION = 1; 417 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 418 | INFOPLIST_FILE = MSBBarChart/Info.plist; 419 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 420 | LD_RUNPATH_SEARCH_PATHS = ( 421 | "$(inherited)", 422 | "@executable_path/Frameworks", 423 | "@loader_path/Frameworks", 424 | ); 425 | PRODUCT_BUNDLE_IDENTIFIER = msb.MSBBarChart; 426 | PRODUCT_NAME = MSBBarChart; 427 | SKIP_INSTALL = YES; 428 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 429 | SWIFT_VERSION = 5.0; 430 | TARGETED_DEVICE_FAMILY = "1,2"; 431 | }; 432 | name = Debug; 433 | }; 434 | 74F3A54D23DEC3DD004A020D /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | CLANG_ENABLE_MODULES = YES; 438 | CODE_SIGN_STYLE = Automatic; 439 | DEFINES_MODULE = YES; 440 | DEVELOPMENT_TEAM = 974NSG8G39; 441 | DYLIB_COMPATIBILITY_VERSION = 1; 442 | DYLIB_CURRENT_VERSION = 1; 443 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 444 | INFOPLIST_FILE = MSBBarChart/Info.plist; 445 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 446 | LD_RUNPATH_SEARCH_PATHS = ( 447 | "$(inherited)", 448 | "@executable_path/Frameworks", 449 | "@loader_path/Frameworks", 450 | ); 451 | PRODUCT_BUNDLE_IDENTIFIER = msb.MSBBarChart; 452 | PRODUCT_NAME = MSBBarChart; 453 | SKIP_INSTALL = YES; 454 | SWIFT_VERSION = 5.0; 455 | TARGETED_DEVICE_FAMILY = "1,2"; 456 | }; 457 | name = Release; 458 | }; 459 | 74F3A57E23DECE97004A020D /* Debug */ = { 460 | isa = XCBuildConfiguration; 461 | buildSettings = { 462 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 463 | CODE_SIGN_STYLE = Automatic; 464 | DEVELOPMENT_TEAM = M8G9M4S72X; 465 | INFOPLIST_FILE = Sample/Info.plist; 466 | LD_RUNPATH_SEARCH_PATHS = ( 467 | "$(inherited)", 468 | "@executable_path/Frameworks", 469 | ); 470 | PRODUCT_BUNDLE_IDENTIFIER = msb; 471 | PRODUCT_NAME = "$(TARGET_NAME)"; 472 | SWIFT_VERSION = 5.0; 473 | TARGETED_DEVICE_FAMILY = "1,2"; 474 | }; 475 | name = Debug; 476 | }; 477 | 74F3A57F23DECE97004A020D /* Release */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 481 | CODE_SIGN_STYLE = Automatic; 482 | DEVELOPMENT_TEAM = M8G9M4S72X; 483 | INFOPLIST_FILE = Sample/Info.plist; 484 | LD_RUNPATH_SEARCH_PATHS = ( 485 | "$(inherited)", 486 | "@executable_path/Frameworks", 487 | ); 488 | PRODUCT_BUNDLE_IDENTIFIER = msb; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | SWIFT_VERSION = 5.0; 491 | TARGETED_DEVICE_FAMILY = "1,2"; 492 | }; 493 | name = Release; 494 | }; 495 | /* End XCBuildConfiguration section */ 496 | 497 | /* Begin XCConfigurationList section */ 498 | 74F3A53D23DEC3DD004A020D /* Build configuration list for PBXProject "MSBBarChart" */ = { 499 | isa = XCConfigurationList; 500 | buildConfigurations = ( 501 | 74F3A54923DEC3DD004A020D /* Debug */, 502 | 74F3A54A23DEC3DD004A020D /* Release */, 503 | ); 504 | defaultConfigurationIsVisible = 0; 505 | defaultConfigurationName = Release; 506 | }; 507 | 74F3A54B23DEC3DD004A020D /* Build configuration list for PBXNativeTarget "MSBBarChart" */ = { 508 | isa = XCConfigurationList; 509 | buildConfigurations = ( 510 | 74F3A54C23DEC3DD004A020D /* Debug */, 511 | 74F3A54D23DEC3DD004A020D /* Release */, 512 | ); 513 | defaultConfigurationIsVisible = 0; 514 | defaultConfigurationName = Release; 515 | }; 516 | 74F3A57D23DECE97004A020D /* Build configuration list for PBXNativeTarget "Sample" */ = { 517 | isa = XCConfigurationList; 518 | buildConfigurations = ( 519 | 74F3A57E23DECE97004A020D /* Debug */, 520 | 74F3A57F23DECE97004A020D /* Release */, 521 | ); 522 | defaultConfigurationIsVisible = 0; 523 | defaultConfigurationName = Release; 524 | }; 525 | /* End XCConfigurationList section */ 526 | }; 527 | rootObject = 74F3A53A23DEC3DD004A020D /* Project object */; 528 | } 529 | -------------------------------------------------------------------------------- /MSBBarChart.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MSBBarChart.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MSBBarChart.xcodeproj/xcshareddata/xcschemes/MSBBarChart.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /MSBBarChart.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /MSBBarChart/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /MSBBarChart/MSBBarChart.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSBBarChart.h 3 | // MSBBarChart 4 | // 5 | // Created by NaotoTakahashi 6 | // Copyright © 2020 msb. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MSBBarChart. 12 | FOUNDATION_EXPORT double MSBBarChartVersionNumber; 13 | 14 | //! Project version string for MSBBarChart. 15 | FOUNDATION_EXPORT const unsigned char MSBBarChartVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /MSBBarChart/Sources/MSBBarChartView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MSBBarChartView.swift 3 | // MSBBarChart 4 | // 5 | // Created by NaotoTakahashi. 6 | // Copyright © 2020 msb. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum MSBBarChartViewOption { 12 | case space(CGFloat) 13 | case bottomSpace(CGFloat) 14 | case topSpace(CGFloat) 15 | case xAxisLabelColor(UIColor) 16 | case yAxisNumberOfInterval(Int) 17 | case yAxisTitle(String) 18 | case xAxisUnitLabel(String) 19 | case isHiddenLabelAboveBar(Bool) 20 | case isHiddenExceptBars(Bool) 21 | case isGradientBar(Bool) 22 | } 23 | 24 | open class MSBBarChartView: UIView { 25 | 26 | open var assignmentOfColor: [Range: UIColor] = [0.0..<0.25: #colorLiteral(red: 0.1294117719, green: 0.2156862766, blue: 0.06666667014, alpha: 1), 0.25..<0.50: #colorLiteral(red: 0.1960784346, green: 0.3411764801, blue: 0.1019607857, alpha: 1), 0.50..<0.75: #colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1), 0.75..<1.0: #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)] // デフォルト 27 | 28 | open var assignmentOfGradient: [Range: [UIColor]] = [0.0..<0.25: [#colorLiteral(red: 0.1294117719, green: 0.2156862766, blue: 0.06666667014, alpha: 1), #colorLiteral(red: 0.1960784346, green: 0.3411764801, blue: 0.1019607857, alpha: 1)], 0.25..<0.50: [#colorLiteral(red: 0.1960784346, green: 0.3411764801, blue: 0.1019607857, alpha: 1), #colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1)], 0.50..<0.75: [#colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1), #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)], 0.75..<1.0: [#colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1), #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)]] 29 | 30 | var space: CGFloat = 12.0 31 | 32 | var topSpace: CGFloat = 40.0 33 | 34 | var bottomSpace: CGFloat = 40.0 35 | 36 | var xAxisLabelColor = #colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1) 37 | 38 | var yAxisNumberOfInterval: Int = 5 39 | 40 | var yAxisTitle: String = "" 41 | 42 | var xAxisUnitLabel: String = "" 43 | 44 | var dataEntries: [BarEntry]? 45 | 46 | private let bothSideMargin: CGFloat = 8.0 47 | 48 | private let minimumBarWidth: CGFloat = 12.0 49 | 50 | private let mainLayer: CAGradientLayer = CAGradientLayer() 51 | 52 | private let scrollView: UIScrollView = UIScrollView() 53 | 54 | private var yAxisLabelWidth: CGFloat = 0.0 55 | 56 | private let yAxisMaxInterval: Int = 10 57 | 58 | private let firstBarXpos: CGFloat = 28.0 59 | 60 | private let barValueBaseMargin: CGFloat = 12.0 61 | 62 | private var startHorizontalLineMargin: CGFloat = 4.0 63 | 64 | private var widthBetweenZeroAndFirst: CGFloat = 16.0 65 | 66 | private var barWidth: CGFloat = 12.0 67 | 68 | private var yAxisLabelFontSize: CGFloat = 8.0 69 | 70 | private var barLabelValueFontSize: CGFloat = 9.0 71 | 72 | private var isHiddenLabelAboveBar: Bool = false 73 | 74 | private var isHiddenExceptBars: Bool = false 75 | 76 | private var isGradientBar: Bool = false 77 | 78 | private var yAxisLabels:[String] = [] 79 | 80 | public override init(frame: CGRect) { 81 | super.init(frame: frame) 82 | setupView() 83 | } 84 | 85 | public convenience init() { 86 | self.init(frame: CGRect.zero) 87 | setupView() 88 | } 89 | 90 | required public init?(coder aDecoder: NSCoder) { 91 | super.init(coder: aDecoder) 92 | setupView() 93 | } 94 | 95 | override open func layoutSubviews() { 96 | scrollView.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height) 97 | } 98 | } 99 | 100 | extension MSBBarChartView { 101 | 102 | private func setupView() { 103 | scrollView.layer.addSublayer(mainLayer) 104 | self.addSubview(scrollView) 105 | } 106 | 107 | private func showEntry(index: Int, entry: BarEntry, maxInterval: CGFloat) { 108 | guard let maxBar = getMaxEntry(), let entryValue = Float(entry.textValue), let maxEntryValue = Float(maxBar.textValue) else { return } 109 | 110 | let barWidthSet = barWidth + space 111 | let xPos: CGFloat = yAxisLabelWidth + bothSideMargin + CGFloat(index) * barWidthSet 112 | var yPos: CGFloat = mainLayer.frame.height - bottomSpace 113 | if (maxEntryValue > 0.0) { 114 | yPos = translateHeightValueToYPosition(value: CGFloat(entryValue / maxEntryValue)) 115 | } 116 | 117 | if !entry.isZeroBar() { 118 | if isGradientBar { 119 | drawGradientBar(xPos: xPos, yPos: yPos, colors: getBarColors(entry)) 120 | } else { 121 | drawBar(xPos: xPos, yPos: yPos, color: getBarColor(entry)) 122 | } 123 | } 124 | 125 | if !isHiddenLabelAboveBar { 126 | drawBarValue(xPos: xPos - barValueBaseMargin / 2, yPos: yPos - barValueBaseMargin, textValue: entry.textValue, color: entry.color) 127 | } 128 | 129 | if !isHiddenExceptBars { 130 | drawXLabel(xPos: xPos - barValueBaseMargin / 2, yPos: mainLayer.frame.height - bottomSpace + 4.0, title: entry.title, textColor: entry.textColor) 131 | } 132 | } 133 | 134 | private func drawBar(xPos: CGFloat, yPos: CGFloat, color: UIColor) { 135 | let barLayer = CALayer() 136 | barLayer.cornerRadius = 4.0 137 | barLayer.frame = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 138 | barLayer.anchorPoint = CGPoint(x: 0.5, y: 1.0) 139 | barLayer.backgroundColor = color.cgColor 140 | mainLayer.addSublayer(barLayer) 141 | executeAnimation(xPos, yPos, color, barLayer) 142 | } 143 | 144 | private func executeAnimation(_ xPos: CGFloat, _ yPos: CGFloat, _ color: UIColor, _ layer: CALayer) { 145 | if yPos != mainLayer.frame.size.height - bottomSpace { 146 | let barLayerBase = CALayer() 147 | barLayerBase.frame = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 148 | barLayerBase.backgroundColor = color.cgColor 149 | barLayerBase.anchorPoint = CGPoint(x: 0.5, y: 1.0) 150 | mainLayer.addSublayer(barLayerBase) 151 | let animation = CABasicAnimation(keyPath: "bounds") 152 | animation.duration = 0.5 153 | animation.fromValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 154 | animation.toValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: -1 * (self.mainLayer.frame.height - self.bottomSpace - yPos) / 2) 155 | animation.isRemovedOnCompletion = false 156 | animation.fillMode = CAMediaTimingFillMode(rawValue: "forwards") 157 | barLayerBase.add(animation, forKey: "bounds") 158 | barLayerBase.frame = animation.toValue as? CGRect ?? CGRect() 159 | } 160 | let subAnimation = CABasicAnimation(keyPath: "bounds") 161 | subAnimation.duration = 0.5 162 | subAnimation.fromValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 163 | subAnimation.toValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: -1 * (self.mainLayer.frame.height - self.bottomSpace - yPos)) 164 | subAnimation.isRemovedOnCompletion = false 165 | subAnimation.fillMode = CAMediaTimingFillMode(rawValue: "forwards") 166 | layer.add(subAnimation, forKey: "bounds") 167 | layer.frame = subAnimation.toValue as? CGRect ?? CGRect() 168 | } 169 | 170 | private func drawGradientBar(xPos: CGFloat, yPos: CGFloat, colors: [UIColor]) { 171 | let barLayer = CAGradientLayer() 172 | barLayer.cornerRadius = 4.0 173 | barLayer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] 174 | barLayer.frame = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 175 | barLayer.anchorPoint = CGPoint(x: 0.5, y: 1.0) 176 | let cgColors: [CGColor] = colors.map({ $0.cgColor }) 177 | barLayer.colors = cgColors 178 | 179 | mainLayer.addSublayer(barLayer) 180 | executeGradientAnimation(xPos, yPos, colors, barLayer) 181 | } 182 | 183 | private func executeGradientAnimation(_ xPos: CGFloat, _ yPos: CGFloat, _ colors: [UIColor], _ layer: CAGradientLayer) { 184 | if yPos != mainLayer.frame.size.height - bottomSpace { 185 | let barLayerBase = CAGradientLayer() 186 | barLayerBase.frame = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 187 | barLayerBase.colors = colors 188 | barLayerBase.anchorPoint = CGPoint(x: 0.5, y: 1.0) 189 | mainLayer.addSublayer(barLayerBase) 190 | 191 | let animation = CABasicAnimation(keyPath: "bounds") 192 | animation.duration = 0.5 193 | animation.fromValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 194 | animation.toValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: -1 * (self.mainLayer.frame.height - self.bottomSpace - yPos) / 2) 195 | animation.isRemovedOnCompletion = false 196 | animation.fillMode = CAMediaTimingFillMode(rawValue: "forwards") 197 | barLayerBase.add(animation, forKey: "bounds") 198 | barLayerBase.frame = animation.toValue as? CGRect ?? CGRect() 199 | } 200 | let subAnimation = CABasicAnimation(keyPath: "bounds") 201 | subAnimation.duration = 0.5 202 | subAnimation.fromValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: 0) 203 | subAnimation.toValue = CGRect(x: xPos, y: self.mainLayer.frame.height - self.bottomSpace, width: self.barWidth, height: -1 * (self.mainLayer.frame.height - self.bottomSpace - yPos)) 204 | subAnimation.isRemovedOnCompletion = false 205 | subAnimation.fillMode = CAMediaTimingFillMode(rawValue: "forwards") 206 | layer.add(subAnimation, forKey: "bounds") 207 | layer.frame = subAnimation.toValue as? CGRect ?? CGRect() 208 | } 209 | 210 | private func drawHorizontalLines() { 211 | self.layer.sublayers?.forEach({ 212 | if $0 is CAShapeLayer { 213 | $0.removeFromSuperlayer() 214 | } 215 | }) 216 | 217 | let translatedHeight = CGFloat(1.0 / CGFloat(yAxisNumberOfInterval)) 218 | var horizontalLineInfos: [Dictionary] = [] 219 | for i in 0...yAxisNumberOfInterval { 220 | let value = CGFloat(translatedHeight) * CGFloat(i) 221 | horizontalLineInfos.append(["value": value]) 222 | } 223 | for lineInfo in horizontalLineInfos { 224 | let xPos = startHorizontalLineMargin + yAxisLabelWidth 225 | let yPos = translateHeightValueToYPosition(value: (lineInfo["value"])!) 226 | let path = UIBezierPath() 227 | path.move(to: CGPoint(x: xPos, y: yPos)) 228 | path.addLine(to: CGPoint(x: scrollView.contentSize.width, y: yPos)) 229 | let lineLayer = CAShapeLayer() 230 | lineLayer.path = path.cgPath 231 | lineLayer.lineWidth = 0.5 232 | lineLayer.strokeColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1).cgColor 233 | mainLayer.insertSublayer(lineLayer, at: 0) 234 | } 235 | } 236 | 237 | private func drawVerticalAxisLabel(_ label: String, _ xPos: CGFloat, _ yPos: CGFloat) { 238 | let labelLayer = CATextLayer() 239 | labelLayer.frame = CGRect(x: xPos, y: yPos, width: yAxisLabelWidth, height: 16) 240 | labelLayer.alignmentMode = CATextLayerAlignmentMode(rawValue: "right") 241 | labelLayer.fontSize = yAxisLabelFontSize 242 | labelLayer.string = label 243 | labelLayer.contentsScale = UIScreen.main.scale 244 | labelLayer.foregroundColor = #colorLiteral(red: 0.631372549, green: 0.631372549, blue: 0.631372549, alpha: 1) 245 | labelLayer.backgroundColor = UIColor.clear.cgColor 246 | mainLayer.addSublayer(labelLayer) 247 | } 248 | 249 | private func setupYAxisLabels() { 250 | guard let maxEntry = getMaxEntry() else { return } 251 | self.yAxisLabels = createYAxisLabels(maxEntry: maxEntry) 252 | decideAxisLabelIfNeededWith(yAxisLabels) 253 | } 254 | 255 | private func drawVericalAxisLabels() { 256 | let translatedUnitHeight = CGFloat(1.0 / CGFloat(yAxisNumberOfInterval)) 257 | drawVerticalAxisLabel("0", 0, mainLayer.frame.height - bottomSpace - 10) 258 | for (i, label) in self.yAxisLabels.enumerated() { 259 | let labelYPosi = translateHeightValueToYPosition(value: translatedUnitHeight * CGFloat(i + 1)) 260 | drawVerticalAxisLabel(label, 0, labelYPosi - 6) 261 | } 262 | 263 | let labelsCount = self.yAxisLabels.count 264 | var yAxisTitleHeight:CGFloat = translateHeightValueToYPosition(value: 1.0) - 20 265 | if (labelsCount > 0) { 266 | yAxisTitleHeight = translateHeightValueToYPosition(value: translatedUnitHeight * CGFloat(labelsCount + 1)) - 6 267 | } 268 | drawVerticalAxisLabel(yAxisTitle, 0, yAxisTitleHeight) 269 | } 270 | 271 | private func decideAxisLabelIfNeededWith(_ yAxisLabels:[String]) { 272 | yAxisLabels.forEach { yAxisLabel in 273 | calcYaxisLabelMaxWidthIfNeeded(yAxisLabel) 274 | } 275 | } 276 | 277 | private func getMaxEntry() -> BarEntry? { 278 | guard let entries = self.dataEntries else { return nil } 279 | for entry in entries where entry.isMax { 280 | return entry 281 | } 282 | return nil 283 | } 284 | 285 | private func createYAxisLabels(maxEntry: BarEntry) -> [String] { 286 | guard let max = Float(maxEntry.textValue) else { return []} 287 | let intervalValue = max / Float(yAxisNumberOfInterval) 288 | var insertValue: Float = 0 289 | var yAxisLabels: [String] = [] 290 | while true { 291 | if insertValue >= max { 292 | return yAxisLabels 293 | } 294 | insertValue += intervalValue 295 | yAxisLabels.append(String(format: "%.02f", Float(insertValue))) 296 | } 297 | } 298 | 299 | private func drawBarValue(xPos: CGFloat, yPos: CGFloat, textValue: String, color: UIColor) { 300 | let textLayer = CATextLayer() 301 | textLayer.frame = CGRect(x: xPos, y: yPos, width: barWidth + barValueBaseMargin, height: 16) 302 | textLayer.foregroundColor = #colorLiteral(red: 0.05882352963, green: 0.180392161, blue: 0.2470588237, alpha: 1) 303 | textLayer.backgroundColor = UIColor.clear.cgColor 304 | textLayer.alignmentMode = CATextLayerAlignmentMode.center 305 | textLayer.contentsScale = UIScreen.main.scale 306 | textLayer.font = CTFontCreateWithName(UIFont.systemFont(ofSize: 0).fontName as CFString, 0, nil) 307 | textLayer.fontSize = barLabelValueFontSize 308 | textLayer.string = textValue 309 | mainLayer.addSublayer(textLayer) 310 | } 311 | 312 | private func drawXLabel(xPos: CGFloat, yPos: CGFloat, title: String, textColor: UIColor) { 313 | let textLayer = CATextLayer() 314 | textLayer.frame = CGRect(x: xPos, y: yPos, width: barWidth + barValueBaseMargin, height: 16) 315 | textLayer.foregroundColor = textColor.cgColor 316 | textLayer.backgroundColor = UIColor.clear.cgColor 317 | textLayer.alignmentMode = CATextLayerAlignmentMode.center 318 | textLayer.contentsScale = UIScreen.main.scale 319 | textLayer.font = CTFontCreateWithName(UIFont.systemFont(ofSize: 0).fontName as CFString, 0, nil) 320 | textLayer.fontSize = barLabelValueFontSize 321 | textLayer.string = title 322 | mainLayer.addSublayer(textLayer) 323 | } 324 | 325 | private func translateHeightValueToYPosition(value: CGFloat) -> CGFloat { 326 | let height: CGFloat = CGFloat(value) * (mainLayer.frame.height - bottomSpace - topSpace) 327 | return mainLayer.frame.height - bottomSpace - height 328 | } 329 | 330 | private func getBarColor(_ barEntity: BarEntry) -> UIColor { 331 | guard let maxBar = getMaxEntry() else { return UIColor.blue } 332 | let ratio = barEntity.height / maxBar.height 333 | let fetchLastAssignmentOfColor = assignmentOfColor.reversed() 334 | var barColor = fetchLastAssignmentOfColor.first?.value 335 | assignmentOfColor.keys.forEach { range in 336 | if (range.contains(ratio)) { 337 | barColor = assignmentOfColor[range] ?? barColor 338 | } 339 | } 340 | return barColor! 341 | } 342 | 343 | private func getBarColors(_ barEntity: BarEntry) -> [UIColor] { 344 | guard let maxBar = getMaxEntry() else { return [UIColor.blue] } 345 | let ratio = barEntity.height / maxBar.height 346 | let fetchLastAssignmentOfGradient = assignmentOfGradient.reversed() 347 | var barColors = fetchLastAssignmentOfGradient.first?.value 348 | assignmentOfGradient.keys.forEach { range in 349 | if (range.contains(ratio)) { 350 | barColors = assignmentOfGradient[range] ?? barColors 351 | } 352 | } 353 | return barColors! 354 | } 355 | 356 | private func calcYaxisLabelMaxWidthIfNeeded(_ label: String) { 357 | let size = label.size(withAttributes: [.font: UIFont.systemFont(ofSize: yAxisLabelFontSize)]) 358 | if self.yAxisLabelWidth < size.width { 359 | self.yAxisLabelWidth = size.width 360 | } 361 | } 362 | 363 | private func prepareParameters() { 364 | self.yAxisLabelWidth = isHiddenExceptBars ? 0 : self.yAxisLabelWidth 365 | self.startHorizontalLineMargin = isHiddenExceptBars ? 0 : self.startHorizontalLineMargin 366 | self.bottomSpace = isHiddenExceptBars ? 0 : self.bottomSpace 367 | } 368 | } 369 | 370 | extension MSBBarChartView { 371 | 372 | open func setOptions(_ options: [MSBBarChartViewOption]) { 373 | for option in options { 374 | switch (option) { 375 | case let .space(value): 376 | space = value 377 | case let .topSpace(value): 378 | topSpace = value 379 | case let .bottomSpace(value): 380 | bottomSpace = value 381 | case let .xAxisLabelColor(value): 382 | xAxisLabelColor = value 383 | case let .yAxisNumberOfInterval(value): 384 | yAxisNumberOfInterval = value 385 | case let .yAxisTitle(value): 386 | yAxisTitle = value 387 | calcYaxisLabelMaxWidthIfNeeded(yAxisTitle) 388 | case let .xAxisUnitLabel(value): 389 | xAxisUnitLabel = value 390 | case let .isHiddenLabelAboveBar(value): 391 | isHiddenLabelAboveBar = value 392 | case let .isHiddenExceptBars(value): 393 | isHiddenExceptBars = value 394 | case let .isGradientBar(value): 395 | isGradientBar = value 396 | } 397 | } 398 | } 399 | 400 | open func start() { 401 | guard let dataSource = self.dataEntries, let max = getMaxEntry(), let interval = Int(max.textValue) else { return } 402 | mainLayer.sublayers?.forEach({ $0.removeFromSuperlayer() }) 403 | 404 | prepareParameters() 405 | setupYAxisLabels() 406 | 407 | barWidth = (scrollView.frame.width - (CGFloat(dataSource.count - 1) * space) - yAxisLabelWidth + startHorizontalLineMargin - bothSideMargin * 2) / CGFloat(dataSource.count) 408 | if barWidth < minimumBarWidth { 409 | barWidth = minimumBarWidth 410 | } 411 | 412 | let contentWidth = yAxisLabelWidth - startHorizontalLineMargin + bothSideMargin + (barWidth + space) * CGFloat(dataSource.count - 1) + barWidth + bothSideMargin 413 | scrollView.contentSize = CGSize(width:contentWidth , height: self.frame.size.height) 414 | mainLayer.frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height) 415 | 416 | if (!isHiddenExceptBars) { 417 | drawVericalAxisLabels() 418 | drawHorizontalLines() 419 | } 420 | 421 | for i in 0.. Bool { 474 | return height <= 0.0 475 | } 476 | } 477 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "MSBBarChart", 8 | platforms: [ 9 | .iOS(.v12) 10 | ], 11 | products: [ 12 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 13 | .library( 14 | name: "MSBBarChart", 15 | targets: ["MSBBarChart"]), 16 | ], 17 | targets: [ 18 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 19 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 20 | .target( 21 | name: "MSBBarChart", 22 | dependencies: [], 23 | path: "MSBBarChart/Sources"), 24 | ] 25 | ) 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MSBBarChart 2 | ![Platform](https://img.shields.io/badge/platform-iOS-lightgrey.svg) 3 | [![Version](https://img.shields.io/cocoapods/v/MSBBarChart.svg?style=flat)](http://cocoapods.org/pods/MSBBarChart) 4 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage) 5 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/komaji/GradientAnimationView/blob/master/LICENSE) 6 | [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) 7 | 8 |

MSBBarChart is an easy to use bar chart library for iOS. 9 |

10 | 11 | 12 | 13 | ## Usage 14 | 15 | ![スクリーンショット 2020-02-04 16 38 16](https://user-images.githubusercontent.com/509448/73723618-caa3e480-476c-11ea-8eb2-4e0424d6820f.png) 16 | 17 | ### if you want to hide label above bar 18 | 19 | ``` 20 | barChart.setOptions([.isHiddenLabelAboveBar(true)]) 21 | ``` 22 | 23 | ### if you want to hide labels and lines 24 | 25 | ``` 26 | barChart.setOptions([.isHiddenExceptBars(true)]) 27 | ``` 28 | 29 | ### if you want to add some gradient to your bars 30 | 31 | ``` 32 | barChart.setOptions([.isGradientBar(true)]) 33 | 34 | // Instead of assignmentOfColor 35 | barChart.assignmentOfGradient = [0.0..<0.25: [#colorLiteral(red: 0.1294117719, green: 0.2156862766, blue: 0.06666667014, alpha: 1),#colorLiteral(red: 0.1960784346, green: 0.3411764801, blue: 0.1019607857, alpha: 1)], 0.25..<0.50: [#colorLiteral(red: 0.1960784346, green: 0.3411764801, blue: 0.1019607857, alpha: 1),#colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1)], 0.50..<0.75:[#colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1),#colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)], 0.75..<1.0: [#colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1),#colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)]] 36 | 37 | ``` 38 | 39 | ## Installation 40 | 41 | ### CocoaPods 42 | 43 | MSBBarChart is available through CocoaPods. To install it, simply add the following line to your Podfile: 44 | 45 | ``` 46 | pod 'MSBBarChart' 47 | ``` 48 | 49 | ### Carthage 50 | 51 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager for Cocoa application. 52 | 53 | ``` bash 54 | $ brew update 55 | $ brew install carthage 56 | ``` 57 | 58 | To integrate MSBBarChart into your Xcode project using Carthage, specify it in your `Cartfile`: 59 | 60 | ``` ogdl 61 | github "misyobun/MSBBarChart" 62 | ``` 63 | 64 | Then, run the following command to build the MetaRod framework: 65 | 66 | ``` bash 67 | $ carthage update --platform iOS 68 | ``` 69 | 70 | You will then have to drag MSBBarChart.framework yourself into your project from the Carthage/Build folder. 71 | -------------------------------------------------------------------------------- /Sample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Sample 4 | // 5 | // Created by 高橋直人 on 2020/01/27. 6 | // Copyright © 2020 msb. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Sample/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 | } -------------------------------------------------------------------------------- /Sample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sample/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 | -------------------------------------------------------------------------------- /Sample/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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Sample/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Sample/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Sample 4 | // 5 | // Created by 高橋直人 on 2020/01/27. 6 | // Copyright © 2020 msb. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | guard let _ = (scene as? UIWindowScene) else { return } 21 | } 22 | 23 | func sceneDidDisconnect(_ scene: UIScene) { 24 | // Called as the scene is being released by the system. 25 | // This occurs shortly after the scene enters the background, or when its session is discarded. 26 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 28 | } 29 | 30 | func sceneDidBecomeActive(_ scene: UIScene) { 31 | // Called when the scene has moved from an inactive state to an active state. 32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 33 | } 34 | 35 | func sceneWillResignActive(_ scene: UIScene) { 36 | // Called when the scene will move from an active state to an inactive state. 37 | // This may occur due to temporary interruptions (ex. an incoming phone call). 38 | } 39 | 40 | func sceneWillEnterForeground(_ scene: UIScene) { 41 | // Called as the scene transitions from the background to the foreground. 42 | // Use this method to undo the changes made on entering the background. 43 | } 44 | 45 | func sceneDidEnterBackground(_ scene: UIScene) { 46 | // Called as the scene transitions from the foreground to the background. 47 | // Use this method to save data, release shared resources, and store enough scene-specific state information 48 | // to restore the scene back to its current state. 49 | } 50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Sample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Sample 4 | // 5 | // Created by NaotoTakahashi 6 | // Copyright © 2020 msb. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MSBBarChart 11 | 12 | class ViewController: UIViewController { 13 | @IBOutlet weak var barChart: MSBBarChartView! 14 | @IBOutlet weak var barChart2: MSBBarChartView! 15 | 16 | override func viewDidAppear(_ animated: Bool) { 17 | super.viewDidAppear(animated) 18 | self.barChart.setOptions([.yAxisTitle("成長"), .yAxisNumberOfInterval(10)]) 19 | self.barChart.assignmentOfColor = [0.0..<0.14: #colorLiteral(red: 0.1019607857, green: 0.2784313858, blue: 0.400000006, alpha: 1), 0.14..<0.28: #colorLiteral(red: 0.1411764771, green: 0.3960784376, blue: 0.5647059083, alpha: 1), 0.28..<0.42: #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1), 0.42..<0.56: #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1), 0.56..<0.70: #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1), 0.70..<1.0: #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)] 20 | self.barChart.setDataEntries(values: [12,24,36,48,60,72,84,96]) 21 | self.barChart.setXAxisUnitTitles(["繊維","IT","鉄鋼","繊維","リテール","不動産","人材派遣","銀行"]) 22 | self.barChart.start() 23 | 24 | self.barChart2.setOptions([.yAxisTitle("売上"), .xAxisUnitLabel("月")]) 25 | self.barChart2.assignmentOfColor = [0.0..<0.14: #colorLiteral(red: 0.3098039329, green: 0.01568627544, blue: 0.1294117719, alpha: 1), 0.14..<0.28: #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 1), 0.28..<0.42: #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 1), 0.42..<0.56: #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1), 0.56..<0.70: #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1), 0.70..<1.0: #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1)] 26 | self.barChart2.setDataEntries(values: [16,32,64,128,256,512,1024,2048]) 27 | self.barChart2.start() 28 | } 29 | 30 | } 31 | 32 | --------------------------------------------------------------------------------