├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── AMVennDiagramView.podspec ├── AMVennDiagramView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── makoto.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ └── AMVennDiagramView.xcscheme └── xcuserdata │ └── makoto.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── AMVennDiagramView ├── AMVennDiagramView.h └── Info.plist ├── LICENSE ├── Package.swift ├── README.md ├── SampleAMVennDiagram ├── SampleAMVennDiagram.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── makoto.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── SampleAMVennDiagram │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Classes │ ├── AppDelegate.swift │ └── ViewController.swift │ └── Info.plist └── Source └── AMVennDiagramView.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode (from gitignore.io) 2 | build/ 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | xcuserdata 12 | *.xccheckout 13 | *.moved-aside 14 | DerivedData 15 | *.hmap 16 | *.ipa 17 | *.xcuserstate 18 | 19 | # CocoaPod 20 | Pods/* 21 | Podfile.lock 22 | 23 | # Carthage 24 | Carthage/Build 25 | 26 | # others 27 | *.swp 28 | !.gitkeep 29 | .DS_Store 30 | UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AMVennDiagramView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "AMVennDiagramView" 3 | s.version = "2.1.0" 4 | s.summary = "AMVennDiagramView is a view can display the diagram like Venn diagram." 5 | s.license = { :type => 'MIT', :file => 'LICENSE' } 6 | s.homepage = "https://github.com/adventam10/AMVennDiagramView" 7 | s.author = { "am10" => "adventam10@gmail.com" } 8 | s.source = { :git => "https://github.com/adventam10/AMVennDiagramView.git", :tag => "#{s.version}" } 9 | s.platform = :ios, "9.0" 10 | s.requires_arc = true 11 | s.source_files = 'Source/*.{swift}' 12 | s.swift_version = "5.0" 13 | end 14 | -------------------------------------------------------------------------------- /AMVennDiagramView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0E02EAE020383374002AB762 /* AMVennDiagramView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E02EADE20383374002AB762 /* AMVennDiagramView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 0EB234D22354909000442A85 /* AMVennDiagramView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB234D12354909000442A85 /* AMVennDiagramView.swift */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 0E02EADB20383374002AB762 /* AMVennDiagramView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AMVennDiagramView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | 0E02EADE20383374002AB762 /* AMVennDiagramView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMVennDiagramView.h; sourceTree = ""; }; 17 | 0E02EADF20383374002AB762 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 18 | 0EB234D12354909000442A85 /* AMVennDiagramView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AMVennDiagramView.swift; sourceTree = ""; }; 19 | /* End PBXFileReference section */ 20 | 21 | /* Begin PBXFrameworksBuildPhase section */ 22 | 0E02EAD720383374002AB762 /* Frameworks */ = { 23 | isa = PBXFrameworksBuildPhase; 24 | buildActionMask = 2147483647; 25 | files = ( 26 | ); 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXFrameworksBuildPhase section */ 30 | 31 | /* Begin PBXGroup section */ 32 | 0E02EAD120383374002AB762 = { 33 | isa = PBXGroup; 34 | children = ( 35 | 0EB234D02354909000442A85 /* Source */, 36 | 0E02EADD20383374002AB762 /* AMVennDiagramView */, 37 | 0E02EADC20383374002AB762 /* Products */, 38 | ); 39 | sourceTree = ""; 40 | }; 41 | 0E02EADC20383374002AB762 /* Products */ = { 42 | isa = PBXGroup; 43 | children = ( 44 | 0E02EADB20383374002AB762 /* AMVennDiagramView.framework */, 45 | ); 46 | name = Products; 47 | sourceTree = ""; 48 | }; 49 | 0E02EADD20383374002AB762 /* AMVennDiagramView */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 0E02EADE20383374002AB762 /* AMVennDiagramView.h */, 53 | 0E02EADF20383374002AB762 /* Info.plist */, 54 | ); 55 | path = AMVennDiagramView; 56 | sourceTree = ""; 57 | }; 58 | 0EB234D02354909000442A85 /* Source */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 0EB234D12354909000442A85 /* AMVennDiagramView.swift */, 62 | ); 63 | path = Source; 64 | sourceTree = ""; 65 | }; 66 | /* End PBXGroup section */ 67 | 68 | /* Begin PBXHeadersBuildPhase section */ 69 | 0E02EAD820383374002AB762 /* Headers */ = { 70 | isa = PBXHeadersBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 0E02EAE020383374002AB762 /* AMVennDiagramView.h in Headers */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXHeadersBuildPhase section */ 78 | 79 | /* Begin PBXNativeTarget section */ 80 | 0E02EADA20383374002AB762 /* AMVennDiagramView */ = { 81 | isa = PBXNativeTarget; 82 | buildConfigurationList = 0E02EAE320383374002AB762 /* Build configuration list for PBXNativeTarget "AMVennDiagramView" */; 83 | buildPhases = ( 84 | 0E02EAD620383374002AB762 /* Sources */, 85 | 0E02EAD720383374002AB762 /* Frameworks */, 86 | 0E02EAD820383374002AB762 /* Headers */, 87 | 0E02EAD920383374002AB762 /* Resources */, 88 | ); 89 | buildRules = ( 90 | ); 91 | dependencies = ( 92 | ); 93 | name = AMVennDiagramView; 94 | productName = AMVennDiagramView; 95 | productReference = 0E02EADB20383374002AB762 /* AMVennDiagramView.framework */; 96 | productType = "com.apple.product-type.framework"; 97 | }; 98 | /* End PBXNativeTarget section */ 99 | 100 | /* Begin PBXProject section */ 101 | 0E02EAD220383374002AB762 /* Project object */ = { 102 | isa = PBXProject; 103 | attributes = { 104 | LastUpgradeCheck = 1020; 105 | ORGANIZATIONNAME = am10; 106 | TargetAttributes = { 107 | 0E02EADA20383374002AB762 = { 108 | CreatedOnToolsVersion = 9.2; 109 | LastSwiftMigration = 1020; 110 | ProvisioningStyle = Automatic; 111 | }; 112 | }; 113 | }; 114 | buildConfigurationList = 0E02EAD520383374002AB762 /* Build configuration list for PBXProject "AMVennDiagramView" */; 115 | compatibilityVersion = "Xcode 8.0"; 116 | developmentRegion = en; 117 | hasScannedForEncodings = 0; 118 | knownRegions = ( 119 | en, 120 | Base, 121 | ); 122 | mainGroup = 0E02EAD120383374002AB762; 123 | productRefGroup = 0E02EADC20383374002AB762 /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | 0E02EADA20383374002AB762 /* AMVennDiagramView */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXResourcesBuildPhase section */ 133 | 0E02EAD920383374002AB762 /* Resources */ = { 134 | isa = PBXResourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | /* End PBXResourcesBuildPhase section */ 141 | 142 | /* Begin PBXSourcesBuildPhase section */ 143 | 0E02EAD620383374002AB762 /* Sources */ = { 144 | isa = PBXSourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 0EB234D22354909000442A85 /* AMVennDiagramView.swift in Sources */, 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXSourcesBuildPhase section */ 152 | 153 | /* Begin XCBuildConfiguration section */ 154 | 0E02EAE120383374002AB762 /* Debug */ = { 155 | isa = XCBuildConfiguration; 156 | buildSettings = { 157 | ALWAYS_SEARCH_USER_PATHS = NO; 158 | CLANG_ANALYZER_NONNULL = YES; 159 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 160 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 161 | CLANG_CXX_LIBRARY = "libc++"; 162 | CLANG_ENABLE_MODULES = YES; 163 | CLANG_ENABLE_OBJC_ARC = YES; 164 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 165 | CLANG_WARN_BOOL_CONVERSION = YES; 166 | CLANG_WARN_COMMA = YES; 167 | CLANG_WARN_CONSTANT_CONVERSION = YES; 168 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 169 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 170 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 171 | CLANG_WARN_EMPTY_BODY = YES; 172 | CLANG_WARN_ENUM_CONVERSION = YES; 173 | CLANG_WARN_INFINITE_RECURSION = YES; 174 | CLANG_WARN_INT_CONVERSION = YES; 175 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 176 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 177 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 178 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 179 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 180 | CLANG_WARN_STRICT_PROTOTYPES = YES; 181 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 182 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 183 | CLANG_WARN_UNREACHABLE_CODE = YES; 184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 185 | CODE_SIGN_IDENTITY = "iPhone Developer"; 186 | COPY_PHASE_STRIP = NO; 187 | CURRENT_PROJECT_VERSION = 1; 188 | DEBUG_INFORMATION_FORMAT = dwarf; 189 | ENABLE_STRICT_OBJC_MSGSEND = YES; 190 | ENABLE_TESTABILITY = YES; 191 | GCC_C_LANGUAGE_STANDARD = gnu11; 192 | GCC_DYNAMIC_NO_PIC = NO; 193 | GCC_NO_COMMON_BLOCKS = YES; 194 | GCC_OPTIMIZATION_LEVEL = 0; 195 | GCC_PREPROCESSOR_DEFINITIONS = ( 196 | "DEBUG=1", 197 | "$(inherited)", 198 | ); 199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 201 | GCC_WARN_UNDECLARED_SELECTOR = YES; 202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 203 | GCC_WARN_UNUSED_FUNCTION = YES; 204 | GCC_WARN_UNUSED_VARIABLE = YES; 205 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 206 | MTL_ENABLE_DEBUG_INFO = YES; 207 | ONLY_ACTIVE_ARCH = YES; 208 | SDKROOT = iphoneos; 209 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 210 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 211 | VERSIONING_SYSTEM = "apple-generic"; 212 | VERSION_INFO_PREFIX = ""; 213 | }; 214 | name = Debug; 215 | }; 216 | 0E02EAE220383374002AB762 /* Release */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | ALWAYS_SEARCH_USER_PATHS = NO; 220 | CLANG_ANALYZER_NONNULL = YES; 221 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 223 | CLANG_CXX_LIBRARY = "libc++"; 224 | CLANG_ENABLE_MODULES = YES; 225 | CLANG_ENABLE_OBJC_ARC = YES; 226 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 227 | CLANG_WARN_BOOL_CONVERSION = YES; 228 | CLANG_WARN_COMMA = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INFINITE_RECURSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 238 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 239 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 241 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 242 | CLANG_WARN_STRICT_PROTOTYPES = YES; 243 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 244 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 245 | CLANG_WARN_UNREACHABLE_CODE = YES; 246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 247 | CODE_SIGN_IDENTITY = "iPhone Developer"; 248 | COPY_PHASE_STRIP = NO; 249 | CURRENT_PROJECT_VERSION = 1; 250 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 251 | ENABLE_NS_ASSERTIONS = NO; 252 | ENABLE_STRICT_OBJC_MSGSEND = YES; 253 | GCC_C_LANGUAGE_STANDARD = gnu11; 254 | GCC_NO_COMMON_BLOCKS = YES; 255 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 256 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 257 | GCC_WARN_UNDECLARED_SELECTOR = YES; 258 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 259 | GCC_WARN_UNUSED_FUNCTION = YES; 260 | GCC_WARN_UNUSED_VARIABLE = YES; 261 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 262 | MTL_ENABLE_DEBUG_INFO = NO; 263 | SDKROOT = iphoneos; 264 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 265 | VALIDATE_PRODUCT = YES; 266 | VERSIONING_SYSTEM = "apple-generic"; 267 | VERSION_INFO_PREFIX = ""; 268 | }; 269 | name = Release; 270 | }; 271 | 0E02EAE420383374002AB762 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | CODE_SIGN_IDENTITY = ""; 275 | CODE_SIGN_STYLE = Automatic; 276 | DEFINES_MODULE = YES; 277 | DEVELOPMENT_TEAM = ""; 278 | DYLIB_COMPATIBILITY_VERSION = 1; 279 | DYLIB_CURRENT_VERSION = 1; 280 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 281 | INFOPLIST_FILE = AMVennDiagramView/Info.plist; 282 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 283 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 284 | PRODUCT_BUNDLE_IDENTIFIER = am10.AMVennDiagramView; 285 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 286 | SKIP_INSTALL = YES; 287 | SWIFT_VERSION = 5.0; 288 | TARGETED_DEVICE_FAMILY = "1,2"; 289 | }; 290 | name = Debug; 291 | }; 292 | 0E02EAE520383374002AB762 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | CODE_SIGN_IDENTITY = ""; 296 | CODE_SIGN_STYLE = Automatic; 297 | DEFINES_MODULE = YES; 298 | DEVELOPMENT_TEAM = ""; 299 | DYLIB_COMPATIBILITY_VERSION = 1; 300 | DYLIB_CURRENT_VERSION = 1; 301 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 302 | INFOPLIST_FILE = AMVennDiagramView/Info.plist; 303 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 304 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 305 | PRODUCT_BUNDLE_IDENTIFIER = am10.AMVennDiagramView; 306 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 307 | SKIP_INSTALL = YES; 308 | SWIFT_VERSION = 5.0; 309 | TARGETED_DEVICE_FAMILY = "1,2"; 310 | }; 311 | name = Release; 312 | }; 313 | /* End XCBuildConfiguration section */ 314 | 315 | /* Begin XCConfigurationList section */ 316 | 0E02EAD520383374002AB762 /* Build configuration list for PBXProject "AMVennDiagramView" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | 0E02EAE120383374002AB762 /* Debug */, 320 | 0E02EAE220383374002AB762 /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | defaultConfigurationName = Release; 324 | }; 325 | 0E02EAE320383374002AB762 /* Build configuration list for PBXNativeTarget "AMVennDiagramView" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | 0E02EAE420383374002AB762 /* Debug */, 329 | 0E02EAE520383374002AB762 /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = 0E02EAD220383374002AB762 /* Project object */; 337 | } 338 | -------------------------------------------------------------------------------- /AMVennDiagramView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AMVennDiagramView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AMVennDiagramView.xcodeproj/project.xcworkspace/xcuserdata/makoto.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adventam10/AMVennDiagramView/13a686b3ee4c366f33ca04317e8cf13c86779394/AMVennDiagramView.xcodeproj/project.xcworkspace/xcuserdata/makoto.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /AMVennDiagramView.xcodeproj/xcshareddata/xcschemes/AMVennDiagramView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /AMVennDiagramView.xcodeproj/xcuserdata/makoto.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | AMVennDiagramView.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /AMVennDiagramView/AMVennDiagramView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AMVennDiagramView.h 3 | // AMVennDiagramView 4 | // 5 | // Created by am10 on 2018/02/17. 6 | // Copyright © 2018年 am10. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for AMVennDiagramView. 12 | FOUNDATION_EXPORT double AMVennDiagramViewVersionNumber; 13 | 14 | //! Project version string for AMVennDiagramView. 15 | FOUNDATION_EXPORT const unsigned char AMVennDiagramViewVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /AMVennDiagramView/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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 adventam10 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /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 | // AMVennDiagramView, https://github.com/adventam10/AMVennDiagramView 5 | // 6 | // Created by am10 on 2019/10/14. 7 | // Copyright © 2019年 am10. All rights reserved. 8 | // 9 | 10 | import PackageDescription 11 | 12 | let package = Package(name: "AMVennDiagramView", 13 | platforms: [.iOS(.v9)], 14 | products: [.library(name: "AMVennDiagramView", 15 | targets: ["AMVennDiagramView"])], 16 | targets: [.target(name: "AMVennDiagramView", 17 | path: "Source")], 18 | swiftLanguageVersions: [.v5]) 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AMVennDiagramView 2 | 3 | ![Pod Platform](https://img.shields.io/cocoapods/p/AMVennDiagramView.svg?style=flat) 4 | ![Pod License](https://img.shields.io/cocoapods/l/AMVennDiagramView.svg?style=flat) 5 | [![Pod Version](https://img.shields.io/cocoapods/v/AMVennDiagramView.svg?style=flat)](http://cocoapods.org/pods/AMVennDiagramView) 6 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) 8 | 9 | `AMVennDiagramView` is a view can display the diagram like Venn diagram. It displays two circles whose area ratio is almost an accurate. 10 | 11 | ## Demo 12 | 13 | 2018-02-17 18 31 11 14 | 15 | 16 | ## Usage 17 | 18 | Create vennDiagramView. 19 | 20 | ```swift 21 | let vennDiagramView = AMVennDiagramView(frame: view.bounds) 22 | view.addSubview(vennDiagramView) 23 | vennDiagramView.setupVennDiagram(value1: 1000, value2: 500, commonValue: 200) 24 | vennDiagramView.dataSource = self 25 | ``` 26 | 27 | Conform to the protocol in the class implementation. 28 | 29 | ```swift 30 | // MARK:- Required 31 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, fillColorForSection section: Int) -> UIColor 32 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, strokeColorForSection section: Int) -> UIColor 33 | 34 | // MARK:- Optional 35 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, titleForSection section: Int, value: CGFloat) -> String // default is empty 36 | func titleForCommonArea(in vennDiagramView: AMVennDiagramView, value: CGFloat) -> String // default is empty 37 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, textColorForSection section: Int) -> UIColor // default is black 38 | func textColorForCommonArea(in vennDiagramView: AMVennDiagramView) -> UIColor // default is black 39 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, textFontForSection section: Int) -> UIFont // default is System 17.0 40 | func textFontForCommonArea(in vennDiagramView: AMVennDiagramView) -> UIFont // default is System 17.0 41 | ``` 42 | 43 | `section` of `value1` is `0`. `section` of `value2` is `1`. 44 | 45 | ## Installation 46 | 47 | ### CocoaPods 48 | 49 | Add this to your Podfile. 50 | 51 | ```ogdl 52 | pod 'AMVennDiagramView' 53 | ``` 54 | 55 | ### Carthage 56 | 57 | Add this to your Cartfile. 58 | 59 | ```ogdl 60 | github "adventam10/AMVennDiagramView" 61 | ``` 62 | 63 | ## License 64 | 65 | MIT 66 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0E02EABD2038314C002AB762 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E02EABB2038314C002AB762 /* Main.storyboard */; }; 11 | 0E02EABF2038314D002AB762 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E02EABE2038314D002AB762 /* Assets.xcassets */; }; 12 | 0E02EAC22038314D002AB762 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E02EAC02038314D002AB762 /* LaunchScreen.storyboard */; }; 13 | 0E02EACC203831E1002AB762 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E02EACA203831E1002AB762 /* AppDelegate.swift */; }; 14 | 0E02EACD203831E1002AB762 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E02EACB203831E1002AB762 /* ViewController.swift */; }; 15 | 0EB234D5235490A200442A85 /* AMVennDiagramView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB234D4235490A200442A85 /* AMVennDiagramView.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 0E02EAB42038314C002AB762 /* SampleAMVennDiagram.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleAMVennDiagram.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 0E02EABC2038314C002AB762 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 21 | 0E02EABE2038314D002AB762 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 22 | 0E02EAC12038314D002AB762 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 23 | 0E02EAC32038314D002AB762 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 24 | 0E02EACA203831E1002AB762 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 25 | 0E02EACB203831E1002AB762 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 26 | 0EB234D4235490A200442A85 /* AMVennDiagramView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AMVennDiagramView.swift; sourceTree = ""; }; 27 | /* End PBXFileReference section */ 28 | 29 | /* Begin PBXFrameworksBuildPhase section */ 30 | 0E02EAB12038314C002AB762 /* Frameworks */ = { 31 | isa = PBXFrameworksBuildPhase; 32 | buildActionMask = 2147483647; 33 | files = ( 34 | ); 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXFrameworksBuildPhase section */ 38 | 39 | /* Begin PBXGroup section */ 40 | 0E02EAAB2038314C002AB762 = { 41 | isa = PBXGroup; 42 | children = ( 43 | 0E02EAB62038314C002AB762 /* SampleAMVennDiagram */, 44 | 0E02EAB52038314C002AB762 /* Products */, 45 | ); 46 | sourceTree = ""; 47 | }; 48 | 0E02EAB52038314C002AB762 /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 0E02EAB42038314C002AB762 /* SampleAMVennDiagram.app */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 0E02EAB62038314C002AB762 /* SampleAMVennDiagram */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 0E02EAC9203831E1002AB762 /* Classes */, 60 | 0E02EABB2038314C002AB762 /* Main.storyboard */, 61 | 0E02EABE2038314D002AB762 /* Assets.xcassets */, 62 | 0E02EAC02038314D002AB762 /* LaunchScreen.storyboard */, 63 | 0E02EAC32038314D002AB762 /* Info.plist */, 64 | ); 65 | path = SampleAMVennDiagram; 66 | sourceTree = ""; 67 | }; 68 | 0E02EAC9203831E1002AB762 /* Classes */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 0EB234D3235490A200442A85 /* Source */, 72 | 0E02EACA203831E1002AB762 /* AppDelegate.swift */, 73 | 0E02EACB203831E1002AB762 /* ViewController.swift */, 74 | ); 75 | path = Classes; 76 | sourceTree = ""; 77 | }; 78 | 0EB234D3235490A200442A85 /* Source */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 0EB234D4235490A200442A85 /* AMVennDiagramView.swift */, 82 | ); 83 | name = Source; 84 | path = ../../../Source; 85 | sourceTree = ""; 86 | }; 87 | /* End PBXGroup section */ 88 | 89 | /* Begin PBXNativeTarget section */ 90 | 0E02EAB32038314C002AB762 /* SampleAMVennDiagram */ = { 91 | isa = PBXNativeTarget; 92 | buildConfigurationList = 0E02EAC62038314D002AB762 /* Build configuration list for PBXNativeTarget "SampleAMVennDiagram" */; 93 | buildPhases = ( 94 | 0E02EAB02038314C002AB762 /* Sources */, 95 | 0E02EAB12038314C002AB762 /* Frameworks */, 96 | 0E02EAB22038314C002AB762 /* Resources */, 97 | ); 98 | buildRules = ( 99 | ); 100 | dependencies = ( 101 | ); 102 | name = SampleAMVennDiagram; 103 | productName = SampleAMVennDiagram; 104 | productReference = 0E02EAB42038314C002AB762 /* SampleAMVennDiagram.app */; 105 | productType = "com.apple.product-type.application"; 106 | }; 107 | /* End PBXNativeTarget section */ 108 | 109 | /* Begin PBXProject section */ 110 | 0E02EAAC2038314C002AB762 /* Project object */ = { 111 | isa = PBXProject; 112 | attributes = { 113 | LastSwiftUpdateCheck = 0920; 114 | LastUpgradeCheck = 1020; 115 | ORGANIZATIONNAME = am10; 116 | TargetAttributes = { 117 | 0E02EAB32038314C002AB762 = { 118 | CreatedOnToolsVersion = 9.2; 119 | LastSwiftMigration = 1020; 120 | ProvisioningStyle = Automatic; 121 | }; 122 | }; 123 | }; 124 | buildConfigurationList = 0E02EAAF2038314C002AB762 /* Build configuration list for PBXProject "SampleAMVennDiagram" */; 125 | compatibilityVersion = "Xcode 8.0"; 126 | developmentRegion = en; 127 | hasScannedForEncodings = 0; 128 | knownRegions = ( 129 | en, 130 | Base, 131 | ); 132 | mainGroup = 0E02EAAB2038314C002AB762; 133 | productRefGroup = 0E02EAB52038314C002AB762 /* Products */; 134 | projectDirPath = ""; 135 | projectRoot = ""; 136 | targets = ( 137 | 0E02EAB32038314C002AB762 /* SampleAMVennDiagram */, 138 | ); 139 | }; 140 | /* End PBXProject section */ 141 | 142 | /* Begin PBXResourcesBuildPhase section */ 143 | 0E02EAB22038314C002AB762 /* Resources */ = { 144 | isa = PBXResourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 0E02EAC22038314D002AB762 /* LaunchScreen.storyboard in Resources */, 148 | 0E02EABF2038314D002AB762 /* Assets.xcassets in Resources */, 149 | 0E02EABD2038314C002AB762 /* Main.storyboard in Resources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXResourcesBuildPhase section */ 154 | 155 | /* Begin PBXSourcesBuildPhase section */ 156 | 0E02EAB02038314C002AB762 /* Sources */ = { 157 | isa = PBXSourcesBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | 0E02EACD203831E1002AB762 /* ViewController.swift in Sources */, 161 | 0EB234D5235490A200442A85 /* AMVennDiagramView.swift in Sources */, 162 | 0E02EACC203831E1002AB762 /* AppDelegate.swift in Sources */, 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXSourcesBuildPhase section */ 167 | 168 | /* Begin PBXVariantGroup section */ 169 | 0E02EABB2038314C002AB762 /* Main.storyboard */ = { 170 | isa = PBXVariantGroup; 171 | children = ( 172 | 0E02EABC2038314C002AB762 /* Base */, 173 | ); 174 | name = Main.storyboard; 175 | sourceTree = ""; 176 | }; 177 | 0E02EAC02038314D002AB762 /* LaunchScreen.storyboard */ = { 178 | isa = PBXVariantGroup; 179 | children = ( 180 | 0E02EAC12038314D002AB762 /* Base */, 181 | ); 182 | name = LaunchScreen.storyboard; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXVariantGroup section */ 186 | 187 | /* Begin XCBuildConfiguration section */ 188 | 0E02EAC42038314D002AB762 /* Debug */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | ALWAYS_SEARCH_USER_PATHS = NO; 192 | CLANG_ANALYZER_NONNULL = YES; 193 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 194 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 195 | CLANG_CXX_LIBRARY = "libc++"; 196 | CLANG_ENABLE_MODULES = YES; 197 | CLANG_ENABLE_OBJC_ARC = YES; 198 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 199 | CLANG_WARN_BOOL_CONVERSION = YES; 200 | CLANG_WARN_COMMA = YES; 201 | CLANG_WARN_CONSTANT_CONVERSION = YES; 202 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 203 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 204 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 205 | CLANG_WARN_EMPTY_BODY = YES; 206 | CLANG_WARN_ENUM_CONVERSION = YES; 207 | CLANG_WARN_INFINITE_RECURSION = YES; 208 | CLANG_WARN_INT_CONVERSION = YES; 209 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 210 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 211 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 212 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 213 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 214 | CLANG_WARN_STRICT_PROTOTYPES = YES; 215 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 216 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 217 | CLANG_WARN_UNREACHABLE_CODE = YES; 218 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 219 | CODE_SIGN_IDENTITY = "iPhone Developer"; 220 | COPY_PHASE_STRIP = NO; 221 | DEBUG_INFORMATION_FORMAT = dwarf; 222 | ENABLE_STRICT_OBJC_MSGSEND = YES; 223 | ENABLE_TESTABILITY = YES; 224 | GCC_C_LANGUAGE_STANDARD = gnu11; 225 | GCC_DYNAMIC_NO_PIC = NO; 226 | GCC_NO_COMMON_BLOCKS = YES; 227 | GCC_OPTIMIZATION_LEVEL = 0; 228 | GCC_PREPROCESSOR_DEFINITIONS = ( 229 | "DEBUG=1", 230 | "$(inherited)", 231 | ); 232 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 233 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 234 | GCC_WARN_UNDECLARED_SELECTOR = YES; 235 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 236 | GCC_WARN_UNUSED_FUNCTION = YES; 237 | GCC_WARN_UNUSED_VARIABLE = YES; 238 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 239 | MTL_ENABLE_DEBUG_INFO = YES; 240 | ONLY_ACTIVE_ARCH = YES; 241 | SDKROOT = iphoneos; 242 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 243 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 244 | }; 245 | name = Debug; 246 | }; 247 | 0E02EAC52038314D002AB762 /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | ALWAYS_SEARCH_USER_PATHS = NO; 251 | CLANG_ANALYZER_NONNULL = YES; 252 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 253 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 254 | CLANG_CXX_LIBRARY = "libc++"; 255 | CLANG_ENABLE_MODULES = YES; 256 | CLANG_ENABLE_OBJC_ARC = YES; 257 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 258 | CLANG_WARN_BOOL_CONVERSION = YES; 259 | CLANG_WARN_COMMA = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INFINITE_RECURSION = YES; 267 | CLANG_WARN_INT_CONVERSION = YES; 268 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 269 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 270 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 271 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 272 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 273 | CLANG_WARN_STRICT_PROTOTYPES = YES; 274 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 275 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 276 | CLANG_WARN_UNREACHABLE_CODE = YES; 277 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 278 | CODE_SIGN_IDENTITY = "iPhone Developer"; 279 | COPY_PHASE_STRIP = NO; 280 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 281 | ENABLE_NS_ASSERTIONS = NO; 282 | ENABLE_STRICT_OBJC_MSGSEND = YES; 283 | GCC_C_LANGUAGE_STANDARD = gnu11; 284 | GCC_NO_COMMON_BLOCKS = YES; 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 287 | GCC_WARN_UNDECLARED_SELECTOR = YES; 288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 289 | GCC_WARN_UNUSED_FUNCTION = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 292 | MTL_ENABLE_DEBUG_INFO = NO; 293 | SDKROOT = iphoneos; 294 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 295 | VALIDATE_PRODUCT = YES; 296 | }; 297 | name = Release; 298 | }; 299 | 0E02EAC72038314D002AB762 /* Debug */ = { 300 | isa = XCBuildConfiguration; 301 | buildSettings = { 302 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 303 | CODE_SIGN_STYLE = Automatic; 304 | DEVELOPMENT_TEAM = ""; 305 | INFOPLIST_FILE = SampleAMVennDiagram/Info.plist; 306 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 307 | PRODUCT_BUNDLE_IDENTIFIER = am10.SampleAMVennDiagram; 308 | PRODUCT_NAME = "$(TARGET_NAME)"; 309 | SWIFT_VERSION = 5.0; 310 | TARGETED_DEVICE_FAMILY = "1,2"; 311 | }; 312 | name = Debug; 313 | }; 314 | 0E02EAC82038314D002AB762 /* Release */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 318 | CODE_SIGN_STYLE = Automatic; 319 | DEVELOPMENT_TEAM = ""; 320 | INFOPLIST_FILE = SampleAMVennDiagram/Info.plist; 321 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 322 | PRODUCT_BUNDLE_IDENTIFIER = am10.SampleAMVennDiagram; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | SWIFT_VERSION = 5.0; 325 | TARGETED_DEVICE_FAMILY = "1,2"; 326 | }; 327 | name = Release; 328 | }; 329 | /* End XCBuildConfiguration section */ 330 | 331 | /* Begin XCConfigurationList section */ 332 | 0E02EAAF2038314C002AB762 /* Build configuration list for PBXProject "SampleAMVennDiagram" */ = { 333 | isa = XCConfigurationList; 334 | buildConfigurations = ( 335 | 0E02EAC42038314D002AB762 /* Debug */, 336 | 0E02EAC52038314D002AB762 /* Release */, 337 | ); 338 | defaultConfigurationIsVisible = 0; 339 | defaultConfigurationName = Release; 340 | }; 341 | 0E02EAC62038314D002AB762 /* Build configuration list for PBXNativeTarget "SampleAMVennDiagram" */ = { 342 | isa = XCConfigurationList; 343 | buildConfigurations = ( 344 | 0E02EAC72038314D002AB762 /* Debug */, 345 | 0E02EAC82038314D002AB762 /* Release */, 346 | ); 347 | defaultConfigurationIsVisible = 0; 348 | defaultConfigurationName = Release; 349 | }; 350 | /* End XCConfigurationList section */ 351 | }; 352 | rootObject = 0E02EAAC2038314C002AB762 /* Project object */; 353 | } 354 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram.xcodeproj/xcuserdata/makoto.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SampleAMVennDiagram.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | SampleAMVennDiagram.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram/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 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram/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 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram/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 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram/Classes/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SampleAMVennDiagram 4 | // 5 | // Created by am10 on 2018/02/17. 6 | // Copyright © 2018年 am10. 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: [UIApplication.LaunchOptionsKey: 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 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram/Classes/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SampleAMVennDiagram 4 | // 5 | // Created by am10 on 2018/02/17. 6 | // Copyright © 2018年 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet weak private var vdV0: AMVennDiagramView! 14 | @IBOutlet weak private var vdV1: AMVennDiagramView! 15 | @IBOutlet weak private var vdV2: AMVennDiagramView! 16 | @IBOutlet weak private var vdV3: AMVennDiagramView! 17 | @IBOutlet weak private var vdV4: AMVennDiagramView! 18 | @IBOutlet weak private var vdV5: AMVennDiagramView! 19 | @IBOutlet weak private var vdV6: AMVennDiagramView! 20 | @IBOutlet weak private var vdV7: AMVennDiagramView! 21 | @IBOutlet weak private var vdV8: AMVennDiagramView! 22 | 23 | override func viewDidLoad() { 24 | super.viewDidLoad() 25 | // Do any additional setup after loading the view, typically from a nib. 26 | 27 | vdV0.setupVennDiagram(value1: 100, value2: 5, commonValue: 0) 28 | vdV0.dataSource = self 29 | 30 | vdV1.setupVennDiagram(value1: 1000, value2: 900, commonValue: 100) 31 | vdV1.dataSource = self 32 | 33 | vdV2.setupVennDiagram(value1: 10000, value2: 7000, commonValue: 7000) 34 | vdV2.dataSource = self 35 | 36 | vdV3.setupVennDiagram(value1: 85, value2: 46, commonValue: 44) 37 | vdV3.dataSource = self 38 | 39 | vdV4.setupVennDiagram(value1: 100, value2: 100, commonValue: 100) 40 | vdV4.dataSource = self 41 | 42 | vdV5.setupVennDiagram(value1: 46, value2: 85, commonValue: 44) 43 | vdV5.dataSource = self 44 | 45 | vdV6.setupVennDiagram(value1: 300, value2: 500, commonValue: 300) 46 | vdV6.dataSource = self 47 | 48 | vdV7.setupVennDiagram(value1: 10000, value2: 20000, commonValue: 4000) 49 | vdV7.dataSource = self 50 | 51 | vdV8.setupVennDiagram(value1: 400, value2: 1000, commonValue: 0) 52 | vdV8.dataSource = self 53 | } 54 | 55 | override func didReceiveMemoryWarning() { 56 | super.didReceiveMemoryWarning() 57 | // Dispose of any resources that can be recreated. 58 | } 59 | } 60 | 61 | extension ViewController: AMVennDiagramViewDataSource { 62 | func vennDiagramView(_ vennDiagramView:AMVennDiagramView, fillColorForSection section: Int) -> UIColor { 63 | let r = CGFloat(arc4random_uniform(255) + 1)/255.0 64 | let g = CGFloat(arc4random_uniform(255) + 1)/255.0 65 | let b = CGFloat(arc4random_uniform(255) + 1)/255.0 66 | 67 | let color = UIColor(red: r, green: g, blue: b, alpha: 0.5) 68 | return color 69 | } 70 | 71 | func vennDiagramView(_ vennDiagramView:AMVennDiagramView, strokeColorForSection section: Int) -> UIColor { 72 | let r = CGFloat(arc4random_uniform(255) + 1)/255.0 73 | let g = CGFloat(arc4random_uniform(255) + 1)/255.0 74 | let b = CGFloat(arc4random_uniform(255) + 1)/255.0 75 | 76 | let color = UIColor(red: r, green: g, blue: b, alpha: 1.0) 77 | return color 78 | } 79 | 80 | func vennDiagramView(_ vennDiagramView:AMVennDiagramView, titleForSection section: Int, value: CGFloat) -> String { 81 | let title = section == 0 ? "A" : "B" 82 | let vakueText = NSString(format: "%.0f", value) as String 83 | return title + "\n" + vakueText 84 | } 85 | 86 | func titleForCommonArea(in vennDiagramView:AMVennDiagramView, value: CGFloat) -> String { 87 | let vakueText = NSString(format: "%.0f", value) as String 88 | return "Common\n" + vakueText 89 | } 90 | 91 | func vennDiagramView(_ vennDiagramView:AMVennDiagramView, textColorForSection section: Int) -> UIColor { 92 | let r = CGFloat(arc4random_uniform(255) + 1)/255.0 93 | let g = CGFloat(arc4random_uniform(255) + 1)/255.0 94 | let b = CGFloat(arc4random_uniform(255) + 1)/255.0 95 | 96 | let color = UIColor(red: r, green: g, blue: b, alpha: 1.0) 97 | return color 98 | } 99 | 100 | func textColorForCommonArea(in vennDiagramView:AMVennDiagramView) -> UIColor { 101 | let r = CGFloat(arc4random_uniform(255) + 1)/255.0 102 | let g = CGFloat(arc4random_uniform(255) + 1)/255.0 103 | let b = CGFloat(arc4random_uniform(255) + 1)/255.0 104 | 105 | let color = UIColor(red: r, green: g, blue: b, alpha: 1.0) 106 | return color 107 | } 108 | 109 | func vennDiagramView(_ vennDiagramView:AMVennDiagramView, textFontForSection section: Int) -> UIFont { 110 | return UIFont.systemFont(ofSize: 17) 111 | } 112 | 113 | func textFontForCommonArea(in vennDiagramView:AMVennDiagramView) -> UIFont { 114 | return UIFont.systemFont(ofSize: 17) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /SampleAMVennDiagram/SampleAMVennDiagram/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Source/AMVennDiagramView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AMVennDiagramView.swift 3 | // AMVennDiagramView, https://github.com/adventam10/AMVennDiagramView 4 | // 5 | // Created by am10 on 2018/02/12. 6 | // Copyright © 2018年 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol AMVennDiagramViewDataSource: AnyObject { 12 | // MARK:- Required 13 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, fillColorForSection section: Int) -> UIColor 14 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, strokeColorForSection section: Int) -> UIColor 15 | // MARK:- Optional 16 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, titleForSection section: Int, value: CGFloat) -> String 17 | func titleForCommonArea(in vennDiagramView: AMVennDiagramView, value: CGFloat) -> String 18 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, textColorForSection section: Int) -> UIColor 19 | func textColorForCommonArea(in vennDiagramView: AMVennDiagramView) -> UIColor 20 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, textFontForSection section: Int) -> UIFont 21 | func textFontForCommonArea(in vennDiagramView: AMVennDiagramView) -> UIFont 22 | } 23 | 24 | public extension AMVennDiagramViewDataSource { 25 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, titleForSection section: Int, value: CGFloat) -> String { 26 | return "" 27 | } 28 | 29 | func titleForCommonArea(in vennDiagramView: AMVennDiagramView, value: CGFloat) -> String { 30 | return "" 31 | } 32 | 33 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, textColorForSection section: Int) -> UIColor { 34 | return .black 35 | } 36 | 37 | func textColorForCommonArea(in vennDiagramView: AMVennDiagramView) -> UIColor { 38 | return .black 39 | } 40 | 41 | func vennDiagramView(_ vennDiagramView: AMVennDiagramView, textFontForSection section: Int) -> UIFont { 42 | return .systemFont(ofSize: 17) 43 | } 44 | 45 | func textFontForCommonArea(in vennDiagramView: AMVennDiagramView) -> UIFont { 46 | return .systemFont(ofSize: 17) 47 | } 48 | } 49 | 50 | public class AMVennDiagramView: UIView { 51 | 52 | weak public var dataSource: AMVennDiagramViewDataSource? 53 | public var commonAreaLineColor: UIColor = .black 54 | 55 | override public var bounds: CGRect { 56 | didSet { 57 | reloadData() 58 | } 59 | } 60 | 61 | private let AMVErrorValue: CGFloat = -1.0 62 | private let AMVLabelSpace: CGFloat = 5 63 | private let AMVCommonAreaLabelLineLength: CGFloat = 10 64 | private let area1Label = UILabel() 65 | private let area2Label = UILabel() 66 | private let commonAreaLabel = UILabel() 67 | 68 | private var commonAreaLineLayer: CAShapeLayer? 69 | private var circle1Layer: CAShapeLayer? 70 | private var circle2Layer: CAShapeLayer? 71 | private var commonValue: CGFloat = 0.0 72 | private var value1: CGFloat = 0.0 73 | private var value2: CGFloat = 0.0 74 | private var distance: CGFloat = 0 75 | 76 | override public func draw(_ rect: CGRect) { 77 | reloadData() 78 | } 79 | 80 | public func setupVennDiagram(value1: CGFloat, value2: CGFloat, commonValue: CGFloat) { 81 | self.value1 = value1 82 | self.value2 = value2 83 | self.commonValue = commonValue 84 | 85 | reloadData() 86 | } 87 | 88 | public func reloadData() { 89 | clear() 90 | prepareCircleLayer() 91 | } 92 | 93 | private func clear() { 94 | distance = 0 95 | circle1Layer?.removeFromSuperlayer() 96 | circle2Layer?.removeFromSuperlayer() 97 | 98 | circle1Layer = nil 99 | circle2Layer = nil 100 | 101 | area1Label.removeFromSuperview() 102 | area2Label.removeFromSuperview() 103 | commonAreaLabel.removeFromSuperview() 104 | commonAreaLineLayer?.removeFromSuperlayer() 105 | commonAreaLineLayer = nil 106 | } 107 | 108 | private func prepareCircleLayer() { 109 | guard let dataSource = dataSource else { 110 | return 111 | } 112 | 113 | setupDistance() 114 | let rate = calculateRate() 115 | if rate == AMVErrorValue { 116 | return 117 | } 118 | 119 | circle1Layer = CAShapeLayer() 120 | circle2Layer = CAShapeLayer() 121 | guard let circle1Layer = circle1Layer, 122 | let circle2Layer = circle2Layer else { 123 | return 124 | } 125 | 126 | let radius1 = calculateRadius(area: value1) * rate 127 | let radius2 = calculateRadius(area: value2) * rate 128 | let center = CGPoint(x: frame.size.width/2, y: frame.size.height/2) 129 | let d = distance * rate 130 | var x1 = center.x - radius1 - (((radius1 + d + radius2)/2) - radius1) 131 | var x2 = x1 + radius1 + d - radius2 132 | if d == abs(radius1 - radius2) { 133 | if radius1 < radius2 { 134 | x2 = center.x - radius2 135 | x1 = x2 136 | } 137 | } 138 | 139 | let strokeColor1 = dataSource.vennDiagramView(self, strokeColorForSection: 0) 140 | let fillColor1 = dataSource.vennDiagramView(self, fillColorForSection: 0) 141 | circle1Layer.frame = CGRect(x: x1, y: center.y - radius1, width: radius1*2, height: radius1*2) 142 | circle1Layer.strokeColor = strokeColor1.cgColor 143 | circle1Layer.fillColor = fillColor1.cgColor 144 | let path1 = UIBezierPath(ovalIn: circle1Layer.bounds) 145 | circle1Layer.path = path1.cgPath 146 | layer.addSublayer(circle1Layer) 147 | 148 | let strokeColor2 = dataSource.vennDiagramView(self, strokeColorForSection: 1) 149 | let fillColor2 = dataSource.vennDiagramView(self, fillColorForSection: 1) 150 | circle2Layer.frame = CGRect(x: x2, y: center.y - radius2, width: radius2*2, height: radius2*2) 151 | circle2Layer.strokeColor = strokeColor2.cgColor 152 | circle2Layer.fillColor = fillColor2.cgColor 153 | let path2 = UIBezierPath(ovalIn: circle2Layer.bounds) 154 | circle2Layer.path = path2.cgPath 155 | layer.addSublayer(circle2Layer) 156 | 157 | showLabels(circle1CenterX: circle1Layer.position.x, 158 | circle2CenterX: circle2Layer.position.x, 159 | radius1: radius1, 160 | radius2: radius2, 161 | distance: d) 162 | } 163 | 164 | private func setupDistance() { 165 | let valueS = value1 < value2 ? value1 : value2 166 | let radius1 = calculateRadius(area: value1) 167 | let radius2 = calculateRadius(area: value2) 168 | 169 | if commonValue == 0 { 170 | distance = radius1 + radius2 171 | return 172 | } else if commonValue == valueS { 173 | distance = abs(radius1 - radius2) 174 | return 175 | } 176 | 177 | let d = calculateDistance(radius1: radius1, radius2: radius2, totalArea: value1 + value2 - commonValue) 178 | distance = compensateDistance(radius1: radius1, radius2: radius2, distance: d) 179 | } 180 | 181 | private func calculateRate() -> CGFloat { 182 | if commonValue < 0 || value1 < 0 || value2 < 0 { 183 | print("AMVennDiagramView Error: negative value") 184 | return AMVErrorValue 185 | } 186 | 187 | if value1 == 0.0 || value2 == 0.0 { 188 | print("AMVennDiagramView Error: zero value") 189 | return AMVErrorValue 190 | } 191 | 192 | let valueL = value1 < value2 ? value2 : value1 193 | let valueS = value1 < value2 ? value1 : value2 194 | 195 | if valueS < commonValue { 196 | print("AMVennDiagramView Error: commonValue is over small value.") 197 | return AMVErrorValue 198 | } 199 | 200 | let radiusL = calculateRadius(area: valueL) 201 | let radiusS = calculateRadius(area: valueS) 202 | 203 | let rateW = frame.size.width / (radiusS + radiusL + distance) 204 | let rateH = frame.size.height / (2*radiusL) 205 | 206 | return rateW < rateH ? rateW*0.9 : rateH*0.9 207 | } 208 | 209 | private func calculateRadius(area: CGFloat) -> CGFloat { 210 | return CGFloat(sqrt(Double(area)/Double.pi)) 211 | } 212 | 213 | //MARK:- Calculate Distance 214 | private func compensateDistance(radius1: CGFloat, radius2: CGFloat, distance: CGFloat) -> CGFloat { 215 | if distance > radius1 + radius2 { 216 | return radius1 + radius2 217 | } 218 | 219 | if distance < abs(radius1-radius2) { 220 | return abs(radius1-radius2) + abs(radius1-radius2)*0.2 221 | } 222 | 223 | return distance 224 | } 225 | 226 | private func calculateDistance(radius1: CGFloat, radius2: CGFloat, totalArea: CGFloat) -> CGFloat { 227 | let r1 = Double(radius1) 228 | let r2 = Double(radius2) 229 | let pi = Double.pi 230 | 231 | var x:Double = ((r1 + r2) + abs(r1-r2))/2 232 | var index:Int = 0 233 | while true { 234 | if x > r1 + r2 || 235 | x < abs(r1-r2) || 236 | x.isNaN || 237 | index > 10000 { 238 | return calculateDistance2(radius1: radius1, radius2: radius2, totalArea: totalArea) 239 | } 240 | 241 | let cos1 = min(max((pow(r1, 2) + pow(x, 2) - pow(r2, 2)) / (2*r1*x), -0.9999), 0.9999) 242 | let cos2 = min(max((pow(r2, 2) + pow(x, 2) - pow(r1, 2)) / (2*r2*x), -0.9999), 0.9999) 243 | 244 | let a = 2*r1 245 | let b = pow(r1, 2) - pow(r2, 2) 246 | let f1 = calculateX(a: a, b: b, x: x, commonF: cos1)*pow(r1, 2) 247 | 248 | let c = 2*r2 249 | let d = pow(r2, 2) - pow(r1, 2) 250 | let f2 = calculateX(a: c, b: d, x: x, commonF: cos2)*pow(r2, 2) 251 | 252 | let area = pow(r1, 2) * (pi - acos(cos1) + sin(acos(cos1))*cos(acos(cos1))) 253 | + pow(r2, 2) * (pi - acos(cos2) + sin(acos(cos2))*cos(acos(cos2))) 254 | let numerator = area - Double(totalArea) 255 | let denominator = f1+f2 256 | 257 | let x2 = x - (numerator/denominator) 258 | if abs((x2 - x)/x) < 0.0001 { 259 | break 260 | } 261 | x = x2 262 | index += 1 263 | } 264 | 265 | return CGFloat(x) 266 | } 267 | 268 | private func calculateX(a: Double, b: Double, x: Double, commonF: Double) -> Double { 269 | let f1 = (-1 / sqrt(1 - pow(commonF, 2))) * ((1/a) - (b/(a*pow(x, 2)))) 270 | 271 | let f2a = (-2*pow(b, 2))/(pow(a, 2)*pow(x, 3)) 272 | let f2b = (2*x)/pow(a, 2) 273 | let f2c = (4*pow(b, 4))/(pow(a, 4)*pow(x, 5)) 274 | let f2d = (8*pow(b, 3))/(pow(a, 4)*pow(x, 3)) 275 | let f2e = (-8*b*x)/pow(a, 4) 276 | let f2f = (-4*pow(x, 3))/pow(a, 4) 277 | 278 | let f2g = sqrt(pow(commonF, 2) - pow(commonF, 4))*2 279 | 280 | let f2 = (f2a+f2b+f2c+f2d+f2e+f2f)/f2g 281 | 282 | return f2 - f1 283 | } 284 | 285 | private func calculateDistance2(radius1: CGFloat, radius2: CGFloat, totalArea: CGFloat) -> CGFloat { 286 | let r1 = Double(radius1) 287 | let r2 = Double(radius2) 288 | let pi = Double.pi 289 | var lowX = abs(r1-r2) 290 | var highX = r1 + r2 291 | var x:Double = (lowX + highX)/2 292 | while true { 293 | if x > r1 + r2 || 294 | x < abs(r1-r2) || 295 | x.isNaN { 296 | break 297 | } 298 | 299 | let cos1 = min(max((pow(r1, 2) + pow(x, 2) - pow(r2, 2)) / (2*r1*x), -0.9999), 0.9999) 300 | let cos2 = min(max((pow(r2, 2) + pow(x, 2) - pow(r1, 2)) / (2*r2*x), -0.9999), 0.9999) 301 | 302 | let area = pow(r1, 2) * (pi - acos(cos1) + sin(acos(cos1))*cos(acos(cos1))) 303 | + pow(r2, 2) * (pi - acos(cos2) + sin(acos(cos2))*cos(acos(cos2))) 304 | let f1 = area - Double(totalArea) 305 | 306 | if abs(f1) < 0.1 { 307 | break 308 | } 309 | 310 | if f1 > 0 { 311 | highX = x 312 | } else { 313 | lowX = x 314 | } 315 | x = (lowX + highX)/2 316 | } 317 | 318 | return CGFloat(x) 319 | } 320 | 321 | //MARK:- Show Labels 322 | private func showLabels(circle1CenterX: CGFloat, circle2CenterX: CGFloat, 323 | radius1: CGFloat, radius2: CGFloat, distance: CGFloat) { 324 | guard let dataSource = dataSource else { 325 | return 326 | } 327 | 328 | let height = frame.size.height/3 329 | showArea1Label(text: dataSource.vennDiagramView(self, titleForSection: 0, value: value1), 330 | textColor: dataSource.vennDiagramView(self, textColorForSection: 0), 331 | font: dataSource.vennDiagramView(self, textFontForSection: 0), 332 | labelHeight: height, 333 | circle1CenterX: circle1CenterX, 334 | circle2CenterX: circle2CenterX, 335 | radius1: radius1, 336 | radius2: radius2) 337 | 338 | showArea2Label(text: dataSource.vennDiagramView(self, titleForSection: 1, value: value2), 339 | textColor: dataSource.vennDiagramView(self, textColorForSection: 1), 340 | font: dataSource.vennDiagramView(self, textFontForSection: 1), 341 | labelHeight: height, 342 | circle1CenterX: circle1CenterX, 343 | circle2CenterX: circle2CenterX, 344 | radius1: radius1, 345 | radius2: radius2) 346 | 347 | showCommonAreaLabel(text: dataSource.titleForCommonArea(in: self, value: commonValue), 348 | textColor: dataSource.textColorForCommonArea(in: self), 349 | font: dataSource.textFontForCommonArea(in: self), 350 | labelHeight: height, 351 | circle1CenterX: circle1CenterX, 352 | circle2CenterX: circle2CenterX, 353 | radius1: radius1, 354 | radius2: radius2, 355 | distance: distance) 356 | } 357 | 358 | private func showArea1Label(text: String, textColor: UIColor, font: UIFont, 359 | labelHeight: CGFloat, circle1CenterX: CGFloat, circle2CenterX: CGFloat, 360 | radius1: CGFloat, radius2: CGFloat) { 361 | let valueS = value1 < value2 ? value1 : value2 362 | var maxX = circle2CenterX - radius2 363 | if commonValue == valueS { 364 | if value1 < value2 { 365 | maxX = circle1CenterX + radius1 366 | } else if value1 == value2 { 367 | maxX = circle1CenterX 368 | } 369 | } 370 | 371 | area1Label.frame = CGRect(x: AMVLabelSpace, 372 | y: frame.size.height/2 - labelHeight/2, 373 | width: maxX - AMVLabelSpace*2, 374 | height: labelHeight) 375 | area1Label.textColor = textColor 376 | area1Label.text = text 377 | area1Label.font = font 378 | area1Label.textAlignment = .right 379 | area1Label.numberOfLines = 0 380 | addSubview(area1Label) 381 | } 382 | 383 | private func showArea2Label(text: String, textColor: UIColor, font: UIFont, 384 | labelHeight: CGFloat, circle1CenterX: CGFloat, circle2CenterX: CGFloat, 385 | radius1: CGFloat, radius2: CGFloat) { 386 | let valueS = value1 < value2 ? value1 : value2 387 | var minX = circle1CenterX + radius1 388 | if commonValue == valueS { 389 | if value2 < value1 { 390 | minX = circle2CenterX - radius2 391 | } else if value1 == value2 { 392 | minX = circle1CenterX 393 | } 394 | } 395 | 396 | let positionX = minX + AMVLabelSpace 397 | area2Label.frame = CGRect(x: positionX, 398 | y: frame.size.height/2 - labelHeight/2, 399 | width: frame.size.width - positionX - AMVLabelSpace, 400 | height: labelHeight) 401 | area2Label.textColor = textColor 402 | area2Label.text = text 403 | area2Label.font = font 404 | area2Label.numberOfLines = 0 405 | addSubview(area2Label) 406 | } 407 | 408 | private func showCommonAreaLabel(text: String, textColor: UIColor, font: UIFont, 409 | labelHeight: CGFloat, circle1CenterX: CGFloat, circle2CenterX: CGFloat, 410 | radius1: CGFloat, radius2: CGFloat, distance: CGFloat) { 411 | if text.isEmpty || commonValue == 0 { 412 | return 413 | } 414 | 415 | let valueS = value1 < value2 ? value1 : value2 416 | var minX = circle1CenterX + radius1 417 | if commonValue == valueS { 418 | if value2 < value1 { 419 | minX = circle2CenterX + 10 420 | } else if value1 == value2 { 421 | minX = circle1CenterX 422 | } 423 | } 424 | 425 | minX += AMVCommonAreaLabelLineLength 426 | commonAreaLabel.frame = CGRect(x: minX, 427 | y: 0, 428 | width: frame.size.width - minX, 429 | height: labelHeight) 430 | commonAreaLabel.textColor = textColor 431 | commonAreaLabel.text = text 432 | commonAreaLabel.font = font 433 | commonAreaLabel.numberOfLines = 0 434 | var rect = commonAreaLabel.frame 435 | commonAreaLabel.sizeToFit() 436 | rect.size.height = commonAreaLabel.frame.size.height 437 | if rect.size.height > labelHeight { 438 | rect.size.height = labelHeight 439 | } 440 | commonAreaLabel.frame = rect 441 | addSubview(commonAreaLabel) 442 | 443 | showCommonAreaLine(circle1CenterX: circle1CenterX, 444 | circle2CenterX: circle2CenterX, 445 | radius1: radius1, 446 | radius2: radius2, 447 | distance: distance) 448 | } 449 | 450 | private func showCommonAreaLine(circle1CenterX: CGFloat, circle2CenterX: CGFloat, 451 | radius1: CGFloat, radius2: CGFloat, distance: CGFloat) { 452 | commonAreaLineLayer = CAShapeLayer() 453 | guard let commonAreaLineLayer = commonAreaLineLayer else { 454 | return 455 | } 456 | 457 | commonAreaLineLayer.frame = bounds 458 | commonAreaLineLayer.strokeColor = commonAreaLineColor.cgColor 459 | commonAreaLineLayer.fillColor = UIColor.clear.cgColor 460 | 461 | let startX = calculateCommonAreaLineStartX(circle1CenterX: circle1CenterX, 462 | circle2CenterX: circle2CenterX, 463 | radius1: radius1, 464 | radius2: radius2, 465 | distance: distance) 466 | let endX = commonAreaLabel.frame.origin.x 467 | let startPoint = CGPoint(x: startX, y: frame.size.height/2) 468 | let point2 = CGPoint(x: endX - AMVCommonAreaLabelLineLength, y: commonAreaLabel.center.y) 469 | let endPoint = CGPoint(x: endX, y: commonAreaLabel.center.y) 470 | 471 | let path = UIBezierPath() 472 | path.move(to: startPoint) 473 | path.addLine(to: point2) 474 | path.addLine(to: endPoint) 475 | commonAreaLineLayer.path = path.cgPath 476 | layer.addSublayer(commonAreaLineLayer) 477 | } 478 | 479 | private func calculateCommonAreaLineStartX(circle1CenterX: CGFloat, circle2CenterX: CGFloat, 480 | radius1: CGFloat, radius2: CGFloat, distance: CGFloat) -> CGFloat { 481 | let valueS = value1 < value2 ? value1 : value2 482 | if commonValue == valueS { 483 | return value2 < value1 ? circle2CenterX : circle1CenterX 484 | } 485 | 486 | let x = circle2CenterX - radius2 487 | let commonAreaLength = radius1 + radius2 - distance 488 | return x + commonAreaLength/2 489 | } 490 | } 491 | --------------------------------------------------------------------------------