├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Example ├── GraphLayout.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── GraphLayout-Example.xcscheme ├── GraphLayout │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── DataSource.swift │ ├── GraphLayoutViewController.swift │ ├── GraphViewController.swift │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── Info.plist ├── Podfile └── Tests │ ├── Info.plist │ └── Tests.swift ├── GraphLayout.podspec ├── GraphLayout ├── Assets │ └── .gitkeep ├── Classes │ ├── .gitkeep │ ├── Graph.swift │ ├── GraphLayout.swift │ ├── GraphView.swift │ ├── graphviz │ │ ├── arith.h │ │ ├── cdt.h │ │ ├── cgraph.h │ │ ├── color.h │ │ ├── geom.h │ │ ├── graphviz_version.h │ │ ├── gvc.h │ │ ├── gvcext.h │ │ ├── gvcjob.h │ │ ├── gvcommon.h │ │ ├── gvconfig.h │ │ ├── gvplugin.h │ │ ├── gvplugin_device.h │ │ ├── gvplugin_layout.h │ │ ├── gvplugin_loadimage.h │ │ ├── gvplugin_render.h │ │ ├── gvplugin_textlayout.h │ │ ├── gvpr.h │ │ ├── pack.h │ │ ├── pathgeom.h │ │ ├── pathplan.h │ │ ├── textspan.h │ │ ├── types.h │ │ ├── usershape.h │ │ └── xdot.h │ └── objc │ │ ├── GVLGraph.h │ │ └── GVLGraph.mm └── lib │ ├── libcdt.a │ ├── libcgraph.a │ ├── libgvc.a │ ├── libgvplugin_core.a │ ├── libgvplugin_dot_layout.a │ ├── libpathplan.a │ └── libxdot.a ├── LICENSE ├── README.md ├── _Pods.xcodeproj └── docs └── images ├── screenshot1.png └── screenshot2.png /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | 39 | *.xcworkspace 40 | Podfile.lock 41 | Example/Pods 42 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/GraphLayout.xcworkspace -scheme GraphLayout-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.1 4 | New: removing node or edge 5 | 6 | ## 0.1.0 7 | Initial release 8 | -------------------------------------------------------------------------------- /Example/GraphLayout.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0F7E805B5484A89DBBFA2485 /* libPods-GraphLayout_Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A2BF47689F86042DBC5D497E /* libPods-GraphLayout_Tests.a */; }; 11 | 5844025EB7F762A612880B88 /* libPods-GraphLayout_Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 710621F97A918B5BED32FDF9 /* libPods-GraphLayout_Example.a */; }; 12 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 17 | EC13AA5C207DC75D00D3D7B2 /* DataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC13AA5B207DC75D00D3D7B2 /* DataSource.swift */; }; 18 | EC1C8891207B367800433024 /* GraphViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1C8890207B367800433024 /* GraphViewController.swift */; }; 19 | ECDF8C97207FA4B000029714 /* GraphLayoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECDF8C96207FA4B000029714 /* GraphLayoutViewController.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 28 | remoteInfo = GraphLayout; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 24C0DDB3519ACD9D22764348 /* Pods-GraphLayout_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphLayout_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GraphLayout_Tests/Pods-GraphLayout_Tests.debug.xcconfig"; sourceTree = ""; }; 34 | 4691C158FBF5DFD522BF6CD6 /* Pods-GraphLayout_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphLayout_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-GraphLayout_Example/Pods-GraphLayout_Example.release.xcconfig"; sourceTree = ""; }; 35 | 506259DCE8E5BA3C30CA3038 /* GraphLayout.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = GraphLayout.podspec; path = ../GraphLayout.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 36 | 607FACD01AFB9204008FA782 /* GraphLayout_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GraphLayout_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 40 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 41 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 42 | 607FACE51AFB9204008FA782 /* GraphLayout_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GraphLayout_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 44 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 45 | 710621F97A918B5BED32FDF9 /* libPods-GraphLayout_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GraphLayout_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 7DE23009B251440CB3237388 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 47 | A2BF47689F86042DBC5D497E /* libPods-GraphLayout_Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GraphLayout_Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | CB121A09E4700BB019FC14AA /* Pods-GraphLayout_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphLayout_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GraphLayout_Example/Pods-GraphLayout_Example.debug.xcconfig"; sourceTree = ""; }; 49 | DE1FA2A866101D43B6248F26 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 50 | E20F2F0C4901B6E51CFE7DB7 /* Pods-GraphLayout_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphLayout_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-GraphLayout_Tests/Pods-GraphLayout_Tests.release.xcconfig"; sourceTree = ""; }; 51 | EC13AA5B207DC75D00D3D7B2 /* DataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataSource.swift; sourceTree = ""; }; 52 | EC1C8890207B367800433024 /* GraphViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewController.swift; sourceTree = ""; }; 53 | ECDF8C96207FA4B000029714 /* GraphLayoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphLayoutViewController.swift; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | 5844025EB7F762A612880B88 /* libPods-GraphLayout_Example.a in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | 0F7E805B5484A89DBBFA2485 /* libPods-GraphLayout_Tests.a in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 607FACC71AFB9204008FA782 = { 77 | isa = PBXGroup; 78 | children = ( 79 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 80 | 607FACD21AFB9204008FA782 /* Example for GraphLayout */, 81 | 607FACE81AFB9204008FA782 /* Tests */, 82 | 607FACD11AFB9204008FA782 /* Products */, 83 | CE149BEDC3B2D00A0717AAC6 /* Pods */, 84 | 66484F681FF00208BFEB902F /* Frameworks */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 607FACD11AFB9204008FA782 /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 607FACD01AFB9204008FA782 /* GraphLayout_Example.app */, 92 | 607FACE51AFB9204008FA782 /* GraphLayout_Tests.xctest */, 93 | ); 94 | name = Products; 95 | sourceTree = ""; 96 | }; 97 | 607FACD21AFB9204008FA782 /* Example for GraphLayout */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | ECDF8C96207FA4B000029714 /* GraphLayoutViewController.swift */, 101 | EC1C8890207B367800433024 /* GraphViewController.swift */, 102 | EC13AA5B207DC75D00D3D7B2 /* DataSource.swift */, 103 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 104 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 105 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 106 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 107 | 607FACD31AFB9204008FA782 /* Supporting Files */, 108 | ); 109 | name = "Example for GraphLayout"; 110 | path = GraphLayout; 111 | sourceTree = ""; 112 | }; 113 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 607FACD41AFB9204008FA782 /* Info.plist */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | 607FACE81AFB9204008FA782 /* Tests */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 125 | 607FACE91AFB9204008FA782 /* Supporting Files */, 126 | ); 127 | path = Tests; 128 | sourceTree = ""; 129 | }; 130 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 607FACEA1AFB9204008FA782 /* Info.plist */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 506259DCE8E5BA3C30CA3038 /* GraphLayout.podspec */, 142 | 7DE23009B251440CB3237388 /* README.md */, 143 | DE1FA2A866101D43B6248F26 /* LICENSE */, 144 | ); 145 | name = "Podspec Metadata"; 146 | sourceTree = ""; 147 | }; 148 | 66484F681FF00208BFEB902F /* Frameworks */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 710621F97A918B5BED32FDF9 /* libPods-GraphLayout_Example.a */, 152 | A2BF47689F86042DBC5D497E /* libPods-GraphLayout_Tests.a */, 153 | ); 154 | name = Frameworks; 155 | sourceTree = ""; 156 | }; 157 | CE149BEDC3B2D00A0717AAC6 /* Pods */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | CB121A09E4700BB019FC14AA /* Pods-GraphLayout_Example.debug.xcconfig */, 161 | 4691C158FBF5DFD522BF6CD6 /* Pods-GraphLayout_Example.release.xcconfig */, 162 | 24C0DDB3519ACD9D22764348 /* Pods-GraphLayout_Tests.debug.xcconfig */, 163 | E20F2F0C4901B6E51CFE7DB7 /* Pods-GraphLayout_Tests.release.xcconfig */, 164 | ); 165 | name = Pods; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 607FACCF1AFB9204008FA782 /* GraphLayout_Example */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "GraphLayout_Example" */; 174 | buildPhases = ( 175 | 4330A5525E90EF6152D8DF59 /* [CP] Check Pods Manifest.lock */, 176 | 607FACCC1AFB9204008FA782 /* Sources */, 177 | 607FACCD1AFB9204008FA782 /* Frameworks */, 178 | 607FACCE1AFB9204008FA782 /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | ); 184 | name = GraphLayout_Example; 185 | productName = GraphLayout; 186 | productReference = 607FACD01AFB9204008FA782 /* GraphLayout_Example.app */; 187 | productType = "com.apple.product-type.application"; 188 | }; 189 | 607FACE41AFB9204008FA782 /* GraphLayout_Tests */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "GraphLayout_Tests" */; 192 | buildPhases = ( 193 | 69F54EE72FEF4AFBDAF61622 /* [CP] Check Pods Manifest.lock */, 194 | 607FACE11AFB9204008FA782 /* Sources */, 195 | 607FACE21AFB9204008FA782 /* Frameworks */, 196 | 607FACE31AFB9204008FA782 /* Resources */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 202 | ); 203 | name = GraphLayout_Tests; 204 | productName = Tests; 205 | productReference = 607FACE51AFB9204008FA782 /* GraphLayout_Tests.xctest */; 206 | productType = "com.apple.product-type.bundle.unit-test"; 207 | }; 208 | /* End PBXNativeTarget section */ 209 | 210 | /* Begin PBXProject section */ 211 | 607FACC81AFB9204008FA782 /* Project object */ = { 212 | isa = PBXProject; 213 | attributes = { 214 | LastSwiftUpdateCheck = 0830; 215 | LastUpgradeCheck = 0930; 216 | ORGANIZATIONNAME = CocoaPods; 217 | TargetAttributes = { 218 | 607FACCF1AFB9204008FA782 = { 219 | CreatedOnToolsVersion = 6.3.1; 220 | DevelopmentTeam = 36FT2XFLPU; 221 | LastSwiftMigration = 0900; 222 | }; 223 | 607FACE41AFB9204008FA782 = { 224 | CreatedOnToolsVersion = 6.3.1; 225 | DevelopmentTeam = 36FT2XFLPU; 226 | LastSwiftMigration = 0900; 227 | TestTargetID = 607FACCF1AFB9204008FA782; 228 | }; 229 | }; 230 | }; 231 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "GraphLayout" */; 232 | compatibilityVersion = "Xcode 3.2"; 233 | developmentRegion = English; 234 | hasScannedForEncodings = 0; 235 | knownRegions = ( 236 | en, 237 | Base, 238 | ); 239 | mainGroup = 607FACC71AFB9204008FA782; 240 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 241 | projectDirPath = ""; 242 | projectRoot = ""; 243 | targets = ( 244 | 607FACCF1AFB9204008FA782 /* GraphLayout_Example */, 245 | 607FACE41AFB9204008FA782 /* GraphLayout_Tests */, 246 | ); 247 | }; 248 | /* End PBXProject section */ 249 | 250 | /* Begin PBXResourcesBuildPhase section */ 251 | 607FACCE1AFB9204008FA782 /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 256 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 257 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | 607FACE31AFB9204008FA782 /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | }; 268 | /* End PBXResourcesBuildPhase section */ 269 | 270 | /* Begin PBXShellScriptBuildPhase section */ 271 | 4330A5525E90EF6152D8DF59 /* [CP] Check Pods Manifest.lock */ = { 272 | isa = PBXShellScriptBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | inputPaths = ( 277 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 278 | "${PODS_ROOT}/Manifest.lock", 279 | ); 280 | name = "[CP] Check Pods Manifest.lock"; 281 | outputPaths = ( 282 | "$(DERIVED_FILE_DIR)/Pods-GraphLayout_Example-checkManifestLockResult.txt", 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | shellPath = /bin/sh; 286 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 287 | showEnvVarsInLog = 0; 288 | }; 289 | 69F54EE72FEF4AFBDAF61622 /* [CP] Check Pods Manifest.lock */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | inputPaths = ( 295 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 296 | "${PODS_ROOT}/Manifest.lock", 297 | ); 298 | name = "[CP] Check Pods Manifest.lock"; 299 | outputPaths = ( 300 | "$(DERIVED_FILE_DIR)/Pods-GraphLayout_Tests-checkManifestLockResult.txt", 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | shellPath = /bin/sh; 304 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 305 | showEnvVarsInLog = 0; 306 | }; 307 | /* End PBXShellScriptBuildPhase section */ 308 | 309 | /* Begin PBXSourcesBuildPhase section */ 310 | 607FACCC1AFB9204008FA782 /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | EC1C8891207B367800433024 /* GraphViewController.swift in Sources */, 315 | ECDF8C97207FA4B000029714 /* GraphLayoutViewController.swift in Sources */, 316 | EC13AA5C207DC75D00D3D7B2 /* DataSource.swift in Sources */, 317 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 318 | ); 319 | runOnlyForDeploymentPostprocessing = 0; 320 | }; 321 | 607FACE11AFB9204008FA782 /* Sources */ = { 322 | isa = PBXSourcesBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | /* End PBXSourcesBuildPhase section */ 330 | 331 | /* Begin PBXTargetDependency section */ 332 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 333 | isa = PBXTargetDependency; 334 | target = 607FACCF1AFB9204008FA782 /* GraphLayout_Example */; 335 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 336 | }; 337 | /* End PBXTargetDependency section */ 338 | 339 | /* Begin PBXVariantGroup section */ 340 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 341 | isa = PBXVariantGroup; 342 | children = ( 343 | 607FACDA1AFB9204008FA782 /* Base */, 344 | ); 345 | name = Main.storyboard; 346 | sourceTree = ""; 347 | }; 348 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 349 | isa = PBXVariantGroup; 350 | children = ( 351 | 607FACDF1AFB9204008FA782 /* Base */, 352 | ); 353 | name = LaunchScreen.xib; 354 | sourceTree = ""; 355 | }; 356 | /* End PBXVariantGroup section */ 357 | 358 | /* Begin XCBuildConfiguration section */ 359 | 607FACED1AFB9204008FA782 /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_MODULES = YES; 366 | CLANG_ENABLE_OBJC_ARC = YES; 367 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 368 | CLANG_WARN_BOOL_CONVERSION = YES; 369 | CLANG_WARN_COMMA = YES; 370 | CLANG_WARN_CONSTANT_CONVERSION = YES; 371 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 372 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 373 | CLANG_WARN_EMPTY_BODY = YES; 374 | CLANG_WARN_ENUM_CONVERSION = YES; 375 | CLANG_WARN_INFINITE_RECURSION = YES; 376 | CLANG_WARN_INT_CONVERSION = YES; 377 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 378 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 379 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 380 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 381 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 382 | CLANG_WARN_STRICT_PROTOTYPES = YES; 383 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 384 | CLANG_WARN_UNREACHABLE_CODE = YES; 385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 386 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 387 | COPY_PHASE_STRIP = NO; 388 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | ENABLE_TESTABILITY = YES; 391 | GCC_C_LANGUAGE_STANDARD = gnu99; 392 | GCC_DYNAMIC_NO_PIC = NO; 393 | GCC_NO_COMMON_BLOCKS = YES; 394 | GCC_OPTIMIZATION_LEVEL = 0; 395 | GCC_PREPROCESSOR_DEFINITIONS = ( 396 | "DEBUG=1", 397 | "$(inherited)", 398 | ); 399 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 407 | MTL_ENABLE_DEBUG_INFO = YES; 408 | ONLY_ACTIVE_ARCH = YES; 409 | SDKROOT = iphoneos; 410 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 411 | }; 412 | name = Debug; 413 | }; 414 | 607FACEE1AFB9204008FA782 /* Release */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ALWAYS_SEARCH_USER_PATHS = NO; 418 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 419 | CLANG_CXX_LIBRARY = "libc++"; 420 | CLANG_ENABLE_MODULES = YES; 421 | CLANG_ENABLE_OBJC_ARC = YES; 422 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 423 | CLANG_WARN_BOOL_CONVERSION = YES; 424 | CLANG_WARN_COMMA = YES; 425 | CLANG_WARN_CONSTANT_CONVERSION = YES; 426 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 427 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 428 | CLANG_WARN_EMPTY_BODY = YES; 429 | CLANG_WARN_ENUM_CONVERSION = YES; 430 | CLANG_WARN_INFINITE_RECURSION = YES; 431 | CLANG_WARN_INT_CONVERSION = YES; 432 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 433 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 434 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 435 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 436 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 437 | CLANG_WARN_STRICT_PROTOTYPES = YES; 438 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 439 | CLANG_WARN_UNREACHABLE_CODE = YES; 440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 441 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 442 | COPY_PHASE_STRIP = NO; 443 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 444 | ENABLE_NS_ASSERTIONS = NO; 445 | ENABLE_STRICT_OBJC_MSGSEND = YES; 446 | GCC_C_LANGUAGE_STANDARD = gnu99; 447 | GCC_NO_COMMON_BLOCKS = YES; 448 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 449 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 450 | GCC_WARN_UNDECLARED_SELECTOR = YES; 451 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 452 | GCC_WARN_UNUSED_FUNCTION = YES; 453 | GCC_WARN_UNUSED_VARIABLE = YES; 454 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 455 | MTL_ENABLE_DEBUG_INFO = NO; 456 | SDKROOT = iphoneos; 457 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 458 | VALIDATE_PRODUCT = YES; 459 | }; 460 | name = Release; 461 | }; 462 | 607FACF01AFB9204008FA782 /* Debug */ = { 463 | isa = XCBuildConfiguration; 464 | baseConfigurationReference = CB121A09E4700BB019FC14AA /* Pods-GraphLayout_Example.debug.xcconfig */; 465 | buildSettings = { 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | DEVELOPMENT_TEAM = 36FT2XFLPU; 468 | INFOPLIST_FILE = GraphLayout/Info.plist; 469 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 470 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 471 | MODULE_NAME = ExampleApp; 472 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 473 | PRODUCT_NAME = "$(TARGET_NAME)"; 474 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 475 | SWIFT_VERSION = 4.0; 476 | TARGETED_DEVICE_FAMILY = "1,2"; 477 | }; 478 | name = Debug; 479 | }; 480 | 607FACF11AFB9204008FA782 /* Release */ = { 481 | isa = XCBuildConfiguration; 482 | baseConfigurationReference = 4691C158FBF5DFD522BF6CD6 /* Pods-GraphLayout_Example.release.xcconfig */; 483 | buildSettings = { 484 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 485 | DEVELOPMENT_TEAM = 36FT2XFLPU; 486 | INFOPLIST_FILE = GraphLayout/Info.plist; 487 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 488 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 489 | MODULE_NAME = ExampleApp; 490 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 491 | PRODUCT_NAME = "$(TARGET_NAME)"; 492 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 493 | SWIFT_VERSION = 4.0; 494 | TARGETED_DEVICE_FAMILY = "1,2"; 495 | }; 496 | name = Release; 497 | }; 498 | 607FACF31AFB9204008FA782 /* Debug */ = { 499 | isa = XCBuildConfiguration; 500 | baseConfigurationReference = 24C0DDB3519ACD9D22764348 /* Pods-GraphLayout_Tests.debug.xcconfig */; 501 | buildSettings = { 502 | DEVELOPMENT_TEAM = 36FT2XFLPU; 503 | FRAMEWORK_SEARCH_PATHS = ( 504 | "$(SDKROOT)/Developer/Library/Frameworks", 505 | "$(inherited)", 506 | ); 507 | GCC_PREPROCESSOR_DEFINITIONS = ( 508 | "DEBUG=1", 509 | "$(inherited)", 510 | ); 511 | INFOPLIST_FILE = Tests/Info.plist; 512 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 513 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 514 | PRODUCT_NAME = "$(TARGET_NAME)"; 515 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 516 | SWIFT_VERSION = 4.0; 517 | }; 518 | name = Debug; 519 | }; 520 | 607FACF41AFB9204008FA782 /* Release */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = E20F2F0C4901B6E51CFE7DB7 /* Pods-GraphLayout_Tests.release.xcconfig */; 523 | buildSettings = { 524 | DEVELOPMENT_TEAM = 36FT2XFLPU; 525 | FRAMEWORK_SEARCH_PATHS = ( 526 | "$(SDKROOT)/Developer/Library/Frameworks", 527 | "$(inherited)", 528 | ); 529 | INFOPLIST_FILE = Tests/Info.plist; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 531 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 534 | SWIFT_VERSION = 4.0; 535 | }; 536 | name = Release; 537 | }; 538 | /* End XCBuildConfiguration section */ 539 | 540 | /* Begin XCConfigurationList section */ 541 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "GraphLayout" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | 607FACED1AFB9204008FA782 /* Debug */, 545 | 607FACEE1AFB9204008FA782 /* Release */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | defaultConfigurationName = Release; 549 | }; 550 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "GraphLayout_Example" */ = { 551 | isa = XCConfigurationList; 552 | buildConfigurations = ( 553 | 607FACF01AFB9204008FA782 /* Debug */, 554 | 607FACF11AFB9204008FA782 /* Release */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "GraphLayout_Tests" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | 607FACF31AFB9204008FA782 /* Debug */, 563 | 607FACF41AFB9204008FA782 /* Release */, 564 | ); 565 | defaultConfigurationIsVisible = 0; 566 | defaultConfigurationName = Release; 567 | }; 568 | /* End XCConfigurationList section */ 569 | }; 570 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 571 | } 572 | -------------------------------------------------------------------------------- /Example/GraphLayout.xcodeproj/xcshareddata/xcschemes/GraphLayout-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /Example/GraphLayout/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. MIT License 6 | // 7 | 8 | import UIKit 9 | 10 | @UIApplicationMain 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | var window: UIWindow? 13 | 14 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 15 | // Override point for customization after application launch. 16 | return true 17 | } 18 | 19 | func applicationWillResignActive(_: UIApplication) { 20 | // 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. 21 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 22 | } 23 | 24 | func applicationDidEnterBackground(_: UIApplication) { 25 | // 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. 26 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 27 | } 28 | 29 | func applicationWillEnterForeground(_: UIApplication) { 30 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 31 | } 32 | 33 | func applicationDidBecomeActive(_: UIApplication) { 34 | // 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. 35 | } 36 | 37 | func applicationWillTerminate(_: UIApplication) { 38 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Example/GraphLayout/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Example/GraphLayout/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 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /Example/GraphLayout/DataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataSource.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. MIT License 6 | // 7 | 8 | import GraphLayout 9 | 10 | class DataSource { 11 | static func createGraph() -> Graph { 12 | let graph: Graph = Graph() 13 | let node1 = graph.addNode("The quick\nbrown fox jumps\nover the lazy\ndog") 14 | let node2 = graph.addNode("node 2") 15 | let node3 = graph.addNode("node 3") 16 | let node4 = graph.addNode("node\n4") 17 | let node5 = graph.addNode("A picture\nis worth\na thousand\nwords") 18 | let node6 = graph.addNode("node 6") 19 | let node7 = graph.addNode("node \n 7") 20 | let node8 = graph.addNode("node 8") 21 | let node9 = graph.addNode("node 9") 22 | let node10 = graph.addNode("node \n 10") 23 | let node11 = graph.addNode("node 11") 24 | let node12 = graph.addNode("node \n 12") 25 | let node13 = graph.addNode("node 13") 26 | let node14 = graph.addNode("node \n 14") 27 | let node15 = graph.addNode("node 15") 28 | _ = graph.addEdge(from: node1, to: node2) 29 | _ = graph.addEdge(from: node1, to: node5) 30 | _ = graph.addEdge(from: node3, to: node4) 31 | _ = graph.addEdge(from: node2, to: node3) 32 | _ = graph.addEdge(from: node4, to: node5) 33 | _ = graph.addEdge(from: node3, to: node5) 34 | _ = graph.addEdge(from: node6, to: node7) 35 | _ = graph.addEdge(from: node7, to: node8) 36 | _ = graph.addEdge(from: node8, to: node9) 37 | _ = graph.addEdge(from: node9, to: node10) 38 | _ = graph.addEdge(from: node1, to: node10) 39 | _ = graph.addEdge(from: node5, to: node10) 40 | _ = graph.addEdge(from: node5, to: node6) 41 | _ = graph.addEdge(from: node6, to: node5) 42 | let e1_8 = graph.addEdge(from: node1, to: node8) 43 | 44 | _ = graph.addEdge(from: node8, to: node1) 45 | let e3_10 = graph.addEdge(from: node3, to: node10) 46 | _ = graph.addEdge(from: node4, to: node9) 47 | _ = graph.addEdge(from: node3, to: node7) 48 | _ = graph.addEdge(from: node2, to: node8) 49 | _ = graph.addEdge(from: node4, to: node8) 50 | _ = graph.addEdge(from: node5, to: node7) 51 | _ = graph.addEdge(from: node5, to: node5) 52 | 53 | _ = graph.addEdge(from: node11, to: node12) 54 | _ = graph.addEdge(from: node12, to: node15) 55 | _ = graph.addEdge(from: node11, to: node13) 56 | _ = graph.addEdge(from: node15, to: node14) 57 | _ = graph.addEdge(from: node15, to: node11) 58 | _ = graph.addEdge(from: node11, to: node1) 59 | _ = graph.addEdge(from: node12, to: node1) 60 | _ = graph.addEdge(from: node10, to: node15) 61 | _ = graph.addEdge(from: node13, to: node6) 62 | let e9_1 = graph.addEdge(from: node9, to: node1) 63 | _ = graph.addEdge(from: node9, to: node11) 64 | _ = graph.addEdge(from: node13, to: node3) 65 | node2.shape = .box 66 | node4.shape = .hexagon 67 | node1.color = UIColor.yellow 68 | node3.fontSize = 24 69 | node3.textColor = UIColor.blue 70 | 71 | e9_1.color = UIColor.red 72 | e3_10.color = UIColor.green 73 | e1_8.weight = 10 74 | e1_8.width = 2 75 | e3_10.weight = 50 76 | e3_10.width = 3 77 | e9_1.weight = 100 78 | e9_1.width = 4 79 | 80 | return graph 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Example/GraphLayout/GraphLayoutViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GraphLayoutViewController.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. MIT License 6 | // 7 | 8 | import GraphLayout 9 | import UIKit 10 | 11 | class GraphLayoutViewController: UIViewController, UICollectionViewDelegate { 12 | @IBOutlet var collectionView: UICollectionView! 13 | 14 | var graph: Graph = DataSource.createGraph() 15 | var layout: GraphLayout! 16 | var selectedNodeIndexPath: IndexPath? 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | layout = GraphLayout() 20 | layout.graph = graph 21 | layout.setup(collectionView: collectionView) 22 | collectionView.delegate = self 23 | updateLayout() 24 | } 25 | 26 | public func collectionView(_: UICollectionView, didSelectItemAt indexPath: IndexPath) { 27 | if indexPath.section == GraphLayoutCellType.Node.rawValue { 28 | let node = graph.nodes[indexPath.item] 29 | graph.removeNode(node: node) 30 | updateLayout() 31 | } 32 | } 33 | 34 | func updateLayout() { 35 | graph.applyLayout() 36 | collectionView.reloadData() 37 | layout.invalidateLayout() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Example/GraphLayout/GraphViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GraphViewController.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. MIT License 6 | // 7 | 8 | import GraphLayout 9 | import UIKit 10 | 11 | class GraphViewController: UIViewController { 12 | @IBOutlet var scrollView: UIScrollView? 13 | 14 | var graph: Graph = DataSource.createGraph() 15 | var graphView: GraphView! 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | graphView = GraphView() 20 | graph.applyLayout() 21 | 22 | graphView.graph = graph 23 | graphView.frame = CGRect(origin: CGPoint.zero, size: graphView.calcSize(graph: graph)) 24 | scrollView?.addSubview(graphView) 25 | scrollView?.contentSize = graphView.bounds.size 26 | graphView.setNeedsDisplay() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Example/GraphLayout/Images.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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/GraphLayout/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '11.0' 2 | 3 | target 'GraphLayout_Example' do 4 | pod 'GraphLayout', :path => '../' 5 | 6 | target 'GraphLayout_Tests' do 7 | inherit! :search_paths 8 | 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | class Tests: XCTestCase { 4 | override func setUp() { 5 | super.setUp() 6 | // Put setup code here. This method is called before the invocation of each test method in the class. 7 | } 8 | 9 | override func tearDown() { 10 | // Put teardown code here. This method is called after the invocation of each test method in the class. 11 | super.tearDown() 12 | } 13 | 14 | func testExample() { 15 | // This is an example of a functional test case. 16 | XCTAssert(true, "Pass") 17 | } 18 | 19 | func testPerformanceExample() { 20 | // This is an example of a performance test case. 21 | measure { 22 | // Put the code you want to measure the time of here. 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /GraphLayout.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint --use-libraries' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Use `pod trunk push --use-libraries` to submit to Cocoapods repo 6 | 7 | Pod::Spec.new do |s| 8 | s.name = 'GraphLayout' 9 | s.version = '0.1.1' 10 | s.summary = 'GraphLayout - UI controls for graph visualization. It is powered by Graphviz' 11 | 12 | s.description = <<-DESC 13 | GraphLayout - UI controls for graph visualization. It is powered by Graphviz. Graph visualization is a way of representing structural information as diagrams of abstract graphs and networks. 14 | DESC 15 | 16 | s.homepage = 'https://github.com/bakhtiyork/GraphLayout' 17 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 18 | s.license = { :type => 'MIT', :file => 'LICENSE' } 19 | s.author = { 'Bakhtiyor Khodjaev' => 'pods@bakhtiyor.com' } 20 | s.source = { :git => 'https://github.com/bakhtiyork/GraphLayout.git', :tag => s.version.to_s } 21 | 22 | s.ios.deployment_target = '11.0' 23 | s.swift_version = '4.0' 24 | 25 | s.source_files = 'GraphLayout/Classes/**/*' 26 | s.libraries = 'z', 'stdc++' 27 | s.vendored_libraries = 'GraphLayout/lib/*.a' 28 | end 29 | -------------------------------------------------------------------------------- /GraphLayout/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/Assets/.gitkeep -------------------------------------------------------------------------------- /GraphLayout/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/Classes/.gitkeep -------------------------------------------------------------------------------- /GraphLayout/Classes/Graph.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Graph.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. 6 | // MIT License 7 | // 8 | 9 | public enum Shape: String { 10 | case rectangle, box, hexagon, polygon, diamond, star, ellipse, circle 11 | } 12 | 13 | public class Edge: Equatable { 14 | fileprivate var gvlEdge: GVLEdge? 15 | 16 | var from: Node 17 | var to: Node 18 | public var color: UIColor = UIColor.black 19 | public var width: Float = 1.0 20 | public var weight: Float = 1 21 | 22 | public init(from node1: Node, to node2: Node) { 23 | from = node1 24 | to = node2 25 | } 26 | 27 | public func getAttribute(name: String) -> String? { 28 | return gvlEdge?.getAttributeForKey(name) 29 | } 30 | 31 | func setAttribute(name: String, value: String) { 32 | gvlEdge?.setAttribute(value, forKey: name) 33 | } 34 | 35 | public func frame() -> CGRect? { 36 | return gvlEdge?.frame() 37 | } 38 | 39 | public func bounds() -> CGRect? { 40 | return gvlEdge?.bounds() 41 | } 42 | 43 | public func body() -> UIBezierPath? { 44 | return gvlEdge?.body() 45 | } 46 | 47 | public func headArrow() -> UIBezierPath? { 48 | return gvlEdge?.headArrow() 49 | } 50 | 51 | public func tailArrow() -> UIBezierPath? { 52 | return gvlEdge?.tailArrow() 53 | } 54 | 55 | func prepare() { 56 | setAttribute(name: "weight", value: weight.description) 57 | } 58 | 59 | public static func == (lhs: Edge, rhs: Edge) -> Bool { 60 | return lhs === rhs 61 | } 62 | } 63 | 64 | public class Node: Equatable { 65 | fileprivate var gvlNode: GVLNode? 66 | 67 | public let label: String 68 | public var color: UIColor = UIColor.white 69 | public var highlihtedColor: UIColor = UIColor.lightGray 70 | public var borderColor: UIColor = UIColor.black 71 | public var borderWidth: Float = 1.0 72 | public var textColor: UIColor = UIColor.black 73 | public var fontSize: Int = 14 74 | public var shape: Shape = .ellipse 75 | 76 | public init(label: String) { 77 | self.label = label 78 | } 79 | 80 | public func getAttribute(name: String) -> String? { 81 | return gvlNode?.getAttributeForKey(name) 82 | } 83 | 84 | func setAttribute(name: String, value: String) { 85 | gvlNode?.setAttribute(value, forKey: name) 86 | } 87 | 88 | public func frame() -> CGRect? { 89 | return gvlNode?.frame() 90 | } 91 | 92 | public func bounds() -> CGRect? { 93 | return gvlNode?.bounds() 94 | } 95 | 96 | public func path() -> UIBezierPath? { 97 | return gvlNode?.path() 98 | } 99 | 100 | func prepare() { 101 | setAttribute(name: "fontsize", value: fontSize.description) 102 | setAttribute(name: "shape", value: shape.rawValue) 103 | } 104 | 105 | public static func == (lhs: Node, rhs: Node) -> Bool { 106 | return lhs === rhs 107 | } 108 | } 109 | 110 | public class SubGraph { 111 | } 112 | 113 | public enum Splines: String { 114 | case spline 115 | case polyline 116 | case ortho 117 | case curved 118 | } 119 | 120 | public class Graph { 121 | fileprivate var gvlGraph: GVLGraph? 122 | 123 | public private(set) var nodes = [Node]() 124 | public private(set) var edges = [Edge]() 125 | public private(set) var size = CGSize.zero 126 | public var splines: Splines = .spline 127 | 128 | public init() { 129 | gvlGraph = GVLGraph() 130 | } 131 | 132 | public func addNode(_ label: String) -> Node { 133 | let node = Node(label: label) 134 | nodes.append(node) 135 | return node 136 | } 137 | 138 | public func removeNode(node: Node) { 139 | guard nodes.count > 1 else { return } 140 | if let index = nodes.index(of: node) { 141 | for edge in edges { 142 | if edge.from == node || edge.to == node { 143 | removeEdge(edge: edge) 144 | } 145 | } 146 | nodes.remove(at: index) 147 | } 148 | } 149 | 150 | public func addEdge(from node1: Node, to node2: Node) -> Edge { 151 | let edge = Edge(from: node1, to: node2) 152 | edges.append(edge) 153 | return edge 154 | } 155 | 156 | public func removeEdge(edge: Edge) { 157 | if let index = edges.index(of: edge) { 158 | edges.remove(at: index) 159 | } 160 | } 161 | 162 | public func applyLayout() { 163 | gvlGraph = GVLGraph() 164 | if let gvlGraph = self.gvlGraph { 165 | for node in nodes { 166 | let gvlNode = gvlGraph.addNode(node.label) 167 | node.gvlNode = gvlNode 168 | node.prepare() 169 | } 170 | for edge in edges { 171 | let gvlEdge = gvlGraph.addEdge(withSource: edge.from.gvlNode, andTarget: edge.to.gvlNode) 172 | edge.gvlEdge = gvlEdge 173 | edge.prepare() 174 | } 175 | 176 | prepare() 177 | gvlGraph.applyLayout() 178 | size = gvlGraph.size() 179 | } 180 | } 181 | 182 | func prepare() { 183 | gvlGraph?.setAttribute(splines.rawValue, forKey: "splines") 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /GraphLayout/Classes/GraphLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GraphLayout.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. 6 | // MIT License 7 | // 8 | 9 | public class GraphLayoutNodeView: UICollectionViewCell { 10 | class func kind() -> String { 11 | return String(describing: GraphLayoutNodeView.self) 12 | } 13 | 14 | public var label: UILabel! 15 | public var maskLayer: CAShapeLayer! 16 | public var shapeLayer: CAShapeLayer! 17 | public fileprivate(set) var node: Node? { 18 | get { 19 | return _node 20 | } 21 | set { 22 | _node = newValue 23 | if let node = _node { 24 | label.text = node.label 25 | label.font = UIFont.systemFont(ofSize: CGFloat(node.fontSize)) 26 | label.textColor = node.textColor 27 | if let bezierPath = node.path(), let frame = node.bounds() { 28 | maskLayer.frame = frame 29 | maskLayer.path = bezierPath.cgPath 30 | 31 | shapeLayer.frame = frame 32 | shapeLayer.path = bezierPath.cgPath 33 | shapeLayer.lineWidth = UIScreen.main.scale * CGFloat(node.borderWidth) 34 | shapeLayer.fillColor = node.color.cgColor 35 | shapeLayer.strokeColor = node.borderColor.cgColor 36 | } else { 37 | maskLayer.frame = frame 38 | shapeLayer.frame = frame 39 | shapeLayer.path = nil 40 | } 41 | } 42 | } 43 | } 44 | 45 | private var _node: Node? 46 | 47 | public required init?(coder aDecoder: NSCoder) { 48 | super.init(coder: aDecoder) 49 | setup() 50 | } 51 | 52 | public override init(frame: CGRect) { 53 | super.init(frame: frame) 54 | setup() 55 | } 56 | 57 | internal func setup() { 58 | isOpaque = false 59 | backgroundColor = UIColor.clear 60 | 61 | maskLayer = CAShapeLayer() 62 | layer.mask = maskLayer 63 | shapeLayer = CAShapeLayer() 64 | layer.addSublayer(shapeLayer) 65 | 66 | label = UILabel() 67 | label.textAlignment = .center 68 | label.translatesAutoresizingMaskIntoConstraints = false 69 | label.numberOfLines = 0 70 | label.autoresizingMask = .flexibleHeight 71 | label.font = UIFont.systemFont(ofSize: 15) 72 | label.sizeToFit() 73 | addSubview(label) 74 | 75 | label.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true 76 | label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true 77 | label.topAnchor.constraint(equalTo: topAnchor).isActive = true 78 | label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true 79 | } 80 | } 81 | 82 | public class GraphLayoutEdgeView: UICollectionViewCell { 83 | class func kind() -> String { 84 | return String(describing: GraphLayoutEdgeView.self) 85 | } 86 | 87 | static let padding: CGFloat = 8 88 | 89 | public fileprivate(set) var edge: Edge? 90 | 91 | public required init?(coder aDecoder: NSCoder) { 92 | super.init(coder: aDecoder) 93 | setup() 94 | } 95 | 96 | public override init(frame: CGRect) { 97 | super.init(frame: frame) 98 | setup() 99 | } 100 | 101 | internal func setup() { 102 | isOpaque = false 103 | backgroundColor = UIColor.clear 104 | } 105 | 106 | public override func draw(_ rect: CGRect) { 107 | super.draw(rect) 108 | if let edge = edge, let context = UIGraphicsGetCurrentContext() { 109 | context.saveGState() 110 | context.translateBy(x: GraphLayoutEdgeView.padding, y: GraphLayoutEdgeView.padding) 111 | edge.color.setStroke() 112 | edge.color.setFill() 113 | let edgeWidth = CGFloat(edge.width) 114 | 115 | if let path = edge.body() { 116 | path.lineWidth = edgeWidth 117 | path.stroke() 118 | } 119 | 120 | if let headArrow = edge.headArrow() { 121 | headArrow.lineWidth = edgeWidth 122 | headArrow.fill() 123 | headArrow.stroke() 124 | } 125 | 126 | if let tailArrow = edge.tailArrow() { 127 | tailArrow.lineWidth = edgeWidth 128 | tailArrow.fill() 129 | tailArrow.stroke() 130 | } 131 | context.restoreGState() 132 | } 133 | } 134 | } 135 | 136 | public enum GraphLayoutCellType: Int { 137 | case Node = 0 138 | case Edge = 1 139 | } 140 | 141 | public class GraphLayout: UICollectionViewLayout, UICollectionViewDataSource { 142 | public var graph: Graph? 143 | /// :nodoc: 144 | internal var cachedAttributes = [NSIndexPath: UICollectionViewLayoutAttributes]() 145 | 146 | public func setup(collectionView: UICollectionView) { 147 | collectionView.register(GraphLayoutNodeView.self, forCellWithReuseIdentifier: "node") 148 | collectionView.register(GraphLayoutEdgeView.self, forCellWithReuseIdentifier: "edge") 149 | collectionView.dataSource = self 150 | collectionView.collectionViewLayout = self 151 | } 152 | 153 | /// :nodoc: 154 | public override func prepare() { 155 | super.prepare() 156 | cachedAttributes.removeAll() 157 | if let graph = self.graph { 158 | let nodes = graph.nodes 159 | let edges = graph.edges 160 | 161 | for (index, node) in nodes.enumerated() { 162 | let indexPath = IndexPath(item: index, section: 0) 163 | let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) 164 | let frame = node.bounds()! 165 | let center = node.frame()!.origin 166 | attributes.frame = frame 167 | attributes.center = CGPoint(x: center.x + frame.width / 2, y: center.y + frame.height / 2) 168 | cachedAttributes[indexPath as NSIndexPath] = attributes 169 | } 170 | for (index, edge) in edges.enumerated() { 171 | let indexPath = IndexPath(item: index, section: 1) 172 | let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) 173 | let bounds = edge.frame()! 174 | attributes.bounds = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: bounds.size.width + 2 * GraphLayoutEdgeView.padding, height: bounds.size.height + 2 * GraphLayoutEdgeView.padding)) 175 | attributes.center = CGPoint(x: bounds.midX, y: bounds.midY) 176 | attributes.zIndex = -1 177 | cachedAttributes[indexPath as NSIndexPath] = attributes 178 | } 179 | } 180 | } 181 | 182 | /// :nodoc: 183 | public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { 184 | return cachedAttributes[indexPath as NSIndexPath] 185 | } 186 | 187 | /// :nodoc: 188 | public override var collectionViewContentSize: CGSize { 189 | return graph?.size ?? CGSize.zero 190 | } 191 | 192 | /// :nodoc: 193 | public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 194 | var layoutAttributes = [UICollectionViewLayoutAttributes]() 195 | for (_, attributes) in cachedAttributes { 196 | if attributes.frame.intersects(rect) { 197 | layoutAttributes.append(attributes) 198 | } 199 | } 200 | return layoutAttributes 201 | } 202 | 203 | public func numberOfSections(in _: UICollectionView) -> Int { 204 | return 2 205 | } 206 | 207 | public func collectionView(_: UICollectionView, numberOfItemsInSection section: Int) -> Int { 208 | if let graph = self.graph { 209 | switch section { 210 | case GraphLayoutCellType.Node.rawValue: 211 | return graph.nodes.count 212 | case GraphLayoutCellType.Edge.rawValue: 213 | return graph.edges.count 214 | default: 215 | return 0 216 | } 217 | } 218 | return 0 219 | } 220 | 221 | public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 222 | if indexPath.section == GraphLayoutCellType.Node.rawValue { 223 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "node", for: indexPath) as! GraphLayoutNodeView 224 | cell.node = graph!.nodes[indexPath.row] 225 | return cell 226 | } else { 227 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "edge", for: indexPath) as! GraphLayoutEdgeView 228 | cell.edge = graph!.edges[indexPath.row] 229 | cell.setNeedsDisplay() 230 | return cell 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /GraphLayout/Classes/GraphView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GraphView.swift 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. 6 | // MIT License 7 | // 8 | 9 | public class GraphView: UIView { 10 | public var graph: Graph? 11 | public var padding: CGFloat = 8 12 | 13 | public func calcSize(graph: Graph) -> CGSize { 14 | if graph.size != CGSize.zero { 15 | let size = graph.size 16 | return CGSize(width: size.width + 2 * padding, height: size.height + 2 * padding) 17 | } 18 | return CGSize.zero 19 | } 20 | 21 | public override func draw(_ rect: CGRect) { 22 | if let graph = self.graph, let context = UIGraphicsGetCurrentContext() { 23 | context.saveGState() 24 | UIColor.white.setFill() 25 | UIRectFill(rect) 26 | context.translateBy(x: padding, y: padding) 27 | 28 | for edge in graph.edges { 29 | if let path = edge.body(), let frame = edge.frame() { 30 | context.saveGState() 31 | let edgeWidth = CGFloat(edge.width) 32 | edge.color.setFill() 33 | edge.color.setStroke() 34 | 35 | let origin = frame.origin 36 | context.translateBy(x: origin.x, y: origin.y) 37 | path.lineWidth = edgeWidth 38 | path.stroke() 39 | if let head = edge.headArrow() { 40 | head.lineWidth = edgeWidth 41 | head.fill() 42 | head.stroke() 43 | } 44 | if let tail = edge.tailArrow() { 45 | tail.lineWidth = edgeWidth 46 | tail.fill() 47 | tail.stroke() 48 | } 49 | context.restoreGState() 50 | } 51 | } 52 | 53 | let paraStyle = NSMutableParagraphStyle() 54 | paraStyle.alignment = NSTextAlignment.center 55 | for node in graph.nodes { 56 | if let path = node.path(), let frame = node.frame() { 57 | context.saveGState() 58 | let origin = frame.origin 59 | context.translateBy(x: origin.x, y: origin.y) 60 | node.color.setFill() 61 | node.borderColor.setStroke() 62 | path.lineWidth = CGFloat(node.borderWidth) 63 | path.fill() 64 | path.stroke() 65 | 66 | let attributes = [ 67 | NSAttributedStringKey.font: UIFont.systemFont(ofSize: CGFloat(node.fontSize)), 68 | NSAttributedStringKey.foregroundColor: node.textColor, 69 | NSAttributedStringKey.paragraphStyle: paraStyle, 70 | ] 71 | let label = node.label 72 | let labelSize = label.size(withAttributes: attributes) 73 | let labelFrame = CGRect( 74 | x: (node.bounds()!.size.width - labelSize.width) / 2, 75 | y: (node.bounds()!.size.height - labelSize.height) / 2, 76 | width: labelSize.width, 77 | height: labelSize.height 78 | ) 79 | label.draw(in: labelFrame, withAttributes: attributes) 80 | context.restoreGState() 81 | } 82 | } 83 | 84 | context.restoreGState() 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/arith.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | /* geometric functions (e.g. on points and boxes) with application to, but 15 | * no specific dependance on graphs */ 16 | 17 | #ifndef GV_ARITH_H 18 | #define GV_ARITH_H 19 | 20 | /* for sincos */ 21 | #ifndef _GNU_SOURCE 22 | #define _GNU_SOURCE 1 23 | #endif 24 | 25 | #include 26 | #ifdef HAVE_VALUES_H 27 | #include 28 | #endif 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #ifdef MIN 36 | #undef MIN 37 | #endif 38 | #define MIN(a,b) ((a)<(b)?(a):(b)) 39 | 40 | #ifdef MAX 41 | #undef MAX 42 | #endif 43 | #define MAX(a,b) ((a)>(b)?(a):(b)) 44 | 45 | #ifdef ABS 46 | #undef ABS 47 | #endif 48 | #define ABS(a) ((a) >= 0 ? (a) : -(a)) 49 | 50 | #define AVG(a,b) ((a + b) / 2) 51 | #define SGN(a) (((a)<0)? -1 : 1) 52 | #define CMP(a,b) (((a)<(b)) ? -1 : (((a)>(b)) ? 1 : 0)) 53 | 54 | #ifndef INT_MAX 55 | #define INT_MAX ((int)(~(unsigned)0 >> 1)) 56 | #endif 57 | 58 | #ifndef INT_MIN 59 | #define INT_MIN (-INT_MAX - 1) 60 | #endif 61 | 62 | #ifndef MAXSHORT 63 | #define MAXSHORT (0x7fff) 64 | #endif 65 | 66 | #ifndef MAXDOUBLE 67 | #define MAXDOUBLE 1.7976931348623157e+308 68 | #endif 69 | 70 | #ifndef MAXFLOAT 71 | #define MAXFLOAT ((float)3.40282347e+38) 72 | #endif 73 | 74 | #ifdef BETWEEN 75 | #undef BETWEEN 76 | #endif 77 | #define BETWEEN(a,b,c) (((a) <= (b)) && ((b) <= (c))) 78 | 79 | #ifndef M_PI 80 | #define M_PI 3.14159265358979323846 81 | #endif 82 | 83 | #ifndef SQRT2 84 | #define SQRT2 1.41421356237309504880 85 | #endif 86 | 87 | #define ROUND(f) ((f>=0)?(int)(f + .5):(int)(f - .5)) 88 | #define RADIANS(deg) ((deg)/180.0 * M_PI) 89 | #define DEGREES(rad) ((rad)/M_PI * 180.0) 90 | 91 | #define SQR(a) ((a) * (a)) 92 | 93 | #ifdef HAVE_SINCOS 94 | extern void sincos(double x, double *s, double *c); 95 | #else 96 | # define sincos(x,s,c) *s = sin(x); *c = cos(x) 97 | #endif 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/cdt.h: -------------------------------------------------------------------------------- 1 | #ifndef _CDT_H 2 | #define _CDT_H 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /* Public interface for the dictionary library 9 | ** 10 | ** Written by Kiem-Phong Vo 11 | */ 12 | 13 | #define CDT_VERSION 20050420L 14 | 15 | #include /* size_t */ 16 | #include 17 | 18 | #ifdef _WIN32 19 | #undef __EXPORT__ 20 | #undef __IMPORT__ 21 | #define __EXPORT__ __declspec (dllexport) 22 | #define __IMPORT__ __declspec (dllimport) 23 | #endif 24 | 25 | typedef struct _dtlink_s Dtlink_t; 26 | typedef struct _dthold_s Dthold_t; 27 | typedef struct _dtdisc_s Dtdisc_t; 28 | typedef struct _dtmethod_s Dtmethod_t; 29 | typedef struct _dtdata_s Dtdata_t; 30 | typedef struct _dt_s Dt_t; 31 | typedef struct _dt_s Dict_t; /* for libdict compatibility */ 32 | typedef struct _dtstat_s Dtstat_t; 33 | typedef void* (*Dtmemory_f)(Dt_t*,void*,size_t,Dtdisc_t*); 34 | typedef void* (*Dtsearch_f)(Dt_t*,void*,int); 35 | typedef void* (*Dtmake_f)(Dt_t*,void*,Dtdisc_t*); 36 | typedef void (*Dtfree_f)(Dt_t*,void*,Dtdisc_t*); 37 | typedef int (*Dtcompar_f)(Dt_t*,void*,void*,Dtdisc_t*); 38 | typedef unsigned int (*Dthash_f)(Dt_t*,void*,Dtdisc_t*); 39 | typedef int (*Dtevent_f)(Dt_t*,int,void*,Dtdisc_t*); 40 | 41 | struct _dtlink_s 42 | { Dtlink_t* right; /* right child */ 43 | union 44 | { unsigned int _hash; /* hash value */ 45 | Dtlink_t* _left; /* left child */ 46 | } hl; 47 | }; 48 | 49 | /* private structure to hold an object */ 50 | struct _dthold_s 51 | { Dtlink_t hdr; /* header */ 52 | void* obj; /* user object */ 53 | }; 54 | 55 | /* method to manipulate dictionary structure */ 56 | struct _dtmethod_s 57 | { Dtsearch_f searchf; /* search function */ 58 | int type; /* type of operation */ 59 | }; 60 | 61 | /* stuff that may be in shared memory */ 62 | struct _dtdata_s 63 | { int type; /* type of dictionary */ 64 | Dtlink_t* here; /* finger to last search element */ 65 | union 66 | { Dtlink_t** _htab; /* hash table */ 67 | Dtlink_t* _head; /* linked list */ 68 | } hh; 69 | int ntab; /* number of hash slots */ 70 | int size; /* number of objects */ 71 | int loop; /* number of nested loops */ 72 | int minp; /* min path before splay, always even */ 73 | /* for hash dt, > 0: fixed table size */ 74 | }; 75 | 76 | /* structure to hold methods that manipulate an object */ 77 | struct _dtdisc_s 78 | { int key; /* where the key begins in an object */ 79 | int size; /* key size and type */ 80 | int link; /* offset to Dtlink_t field */ 81 | Dtmake_f makef; /* object constructor */ 82 | Dtfree_f freef; /* object destructor */ 83 | Dtcompar_f comparf;/* to compare two objects */ 84 | Dthash_f hashf; /* to compute hash value of an object */ 85 | Dtmemory_f memoryf;/* to allocate/free memory */ 86 | Dtevent_f eventf; /* to process events */ 87 | }; 88 | 89 | #define DTDISC(dc,ky,sz,lk,mkf,frf,cmpf,hshf,memf,evf) \ 90 | ( (dc)->key = (ky), (dc)->size = (sz), (dc)->link = (lk), \ 91 | (dc)->makef = (mkf), (dc)->freef = (frf), \ 92 | (dc)->comparf = (cmpf), (dc)->hashf = (hshf), \ 93 | (dc)->memoryf = (memf), (dc)->eventf = (evf) ) 94 | 95 | /* the dictionary structure itself */ 96 | struct _dt_s 97 | { Dtsearch_f searchf;/* search function */ 98 | Dtdisc_t* disc; /* method to manipulate objs */ 99 | Dtdata_t* data; /* sharable data */ 100 | Dtmemory_f memoryf;/* function to alloc/free memory */ 101 | Dtmethod_t* meth; /* dictionary method */ 102 | int type; /* type information */ 103 | int nview; /* number of parent view dictionaries */ 104 | Dt_t* view; /* next on viewpath */ 105 | Dt_t* walk; /* dictionary being walked */ 106 | void* user; /* for user's usage */ 107 | }; 108 | 109 | /* structure to get status of a dictionary */ 110 | struct _dtstat_s 111 | { int dt_meth; /* method type */ 112 | int dt_size; /* number of elements */ 113 | int dt_n; /* number of chains or levels */ 114 | int dt_max; /* max size of a chain or a level */ 115 | int* dt_count; /* counts of chains or levels by size */ 116 | }; 117 | 118 | /* flag set if the last search operation actually found the object */ 119 | #define DT_FOUND 0100000 120 | 121 | /* supported storage methods */ 122 | #define DT_SET 0000001 /* set with unique elements */ 123 | #define DT_BAG 0000002 /* multiset */ 124 | #define DT_OSET 0000004 /* ordered set (self-adjusting tree) */ 125 | #define DT_OBAG 0000010 /* ordered multiset */ 126 | #define DT_LIST 0000020 /* linked list */ 127 | #define DT_STACK 0000040 /* stack: insert/delete at top */ 128 | #define DT_QUEUE 0000100 /* queue: insert at top, delete at tail */ 129 | #define DT_DEQUE 0000200 /* deque: insert at top, append at tail */ 130 | #define DT_METHODS 0000377 /* all currently supported methods */ 131 | 132 | /* asserts to dtdisc() */ 133 | #define DT_SAMECMP 0000001 /* compare methods equivalent */ 134 | #define DT_SAMEHASH 0000002 /* hash methods equivalent */ 135 | 136 | /* types of search */ 137 | #define DT_INSERT 0000001 /* insert object if not found */ 138 | #define DT_DELETE 0000002 /* delete object if found */ 139 | #define DT_SEARCH 0000004 /* look for an object */ 140 | #define DT_NEXT 0000010 /* look for next element */ 141 | #define DT_PREV 0000020 /* find previous element */ 142 | #define DT_RENEW 0000040 /* renewing an object */ 143 | #define DT_CLEAR 0000100 /* clearing all objects */ 144 | #define DT_FIRST 0000200 /* get first object */ 145 | #define DT_LAST 0000400 /* get last object */ 146 | #define DT_MATCH 0001000 /* find object matching key */ 147 | #define DT_VSEARCH 0002000 /* search using internal representation */ 148 | #define DT_ATTACH 0004000 /* attach an object to the dictionary */ 149 | #define DT_DETACH 0010000 /* detach an object from the dictionary */ 150 | #define DT_APPEND 0020000 /* used on Dtlist to append an object */ 151 | 152 | /* events */ 153 | #define DT_OPEN 1 /* a dictionary is being opened */ 154 | #define DT_CLOSE 2 /* a dictionary is being closed */ 155 | #define DT_DISC 3 /* discipline is about to be changed */ 156 | #define DT_METH 4 /* method is about to be changed */ 157 | #define DT_ENDOPEN 5 /* dtopen() is done */ 158 | #define DT_ENDCLOSE 6 /* dtclose() is done */ 159 | #define DT_HASHSIZE 7 /* setting hash table size */ 160 | 161 | /* public data */ 162 | #if defined(_BLD_cdt) && defined(__EXPORT__) 163 | #define extern __EXPORT__ 164 | #endif 165 | #if !defined(_BLD_cdt) && defined(__IMPORT__) 166 | #define extern __IMPORT__ 167 | #endif 168 | 169 | extern Dtmethod_t* Dtset; 170 | extern Dtmethod_t* Dtbag; 171 | extern Dtmethod_t* Dtoset; 172 | extern Dtmethod_t* Dtobag; 173 | extern Dtmethod_t* Dtlist; 174 | extern Dtmethod_t* Dtstack; 175 | extern Dtmethod_t* Dtqueue; 176 | extern Dtmethod_t* Dtdeque; 177 | 178 | /* compatibility stuff; will go away */ 179 | #ifndef KPVDEL 180 | extern Dtmethod_t* Dtorder; 181 | extern Dtmethod_t* Dttree; 182 | extern Dtmethod_t* Dthash; 183 | extern Dtmethod_t _Dttree; 184 | extern Dtmethod_t _Dthash; 185 | extern Dtmethod_t _Dtlist; 186 | extern Dtmethod_t _Dtqueue; 187 | extern Dtmethod_t _Dtstack; 188 | #endif 189 | 190 | #undef extern 191 | 192 | /* public functions */ 193 | #if defined(_BLD_cdt) && defined(__EXPORT__) 194 | #define extern __EXPORT__ 195 | #endif 196 | 197 | extern Dt_t* dtopen(Dtdisc_t*, Dtmethod_t*); 198 | extern int dtclose(Dt_t*); 199 | extern Dt_t* dtview(Dt_t*, Dt_t*); 200 | extern Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t*, int); 201 | extern Dtmethod_t* dtmethod(Dt_t*, Dtmethod_t*); 202 | 203 | extern Dtlink_t* dtflatten(Dt_t*); 204 | extern Dtlink_t* dtextract(Dt_t*); 205 | extern int dtrestore(Dt_t*, Dtlink_t*); 206 | 207 | extern int dttreeset(Dt_t*, int, int); 208 | 209 | extern int dtwalk(Dt_t*, int(*)(Dt_t*,void*,void*), void*); 210 | 211 | extern void* dtrenew(Dt_t*, void*); 212 | 213 | extern int dtsize(Dt_t*); 214 | extern int dtstat(Dt_t*, Dtstat_t*, int); 215 | extern unsigned int dtstrhash(unsigned int, void*, int); 216 | 217 | #undef extern 218 | 219 | /* internal functions for translating among holder, object and key */ 220 | #define _DT(dt) ((Dt_t*)(dt)) 221 | #define _DTDSC(dc,ky,sz,lk,cmpf) \ 222 | (ky = dc->key, sz = dc->size, lk = dc->link, cmpf = dc->comparf) 223 | #define _DTLNK(o,lk) ((Dtlink_t*)((char*)(o) + lk) ) 224 | #define _DTOBJ(e,lk) (lk < 0 ? ((Dthold_t*)(e))->obj : (void*)((char*)(e) - lk) ) 225 | #define _DTKEY(o,ky,sz) (void*)(sz < 0 ? *((char**)((char*)(o)+ky)) : ((char*)(o)+ky)) 226 | 227 | #define _DTCMP(dt,k1,k2,dc,cmpf,sz) \ 228 | (cmpf ? (*cmpf)(dt,k1,k2,dc) : \ 229 | (sz <= 0 ? strcmp(k1,k2) : memcmp(k1,k2,sz)) ) 230 | #define _DTHSH(dt,ky,dc,sz) (dc->hashf ? (*dc->hashf)(dt,ky,dc) : dtstrhash(0,ky,sz) ) 231 | 232 | /* special search function for tree structure only */ 233 | #define _DTMTCH(dt,key,action) \ 234 | do { Dtlink_t* _e; void *_o, *_k, *_key; Dtdisc_t* _dc; \ 235 | int _ky, _sz, _lk, _cmp; Dtcompar_f _cmpf; \ 236 | _dc = (dt)->disc; _DTDSC(_dc, _ky, _sz, _lk, _cmpf); \ 237 | _key = (key); \ 238 | for(_e = (dt)->data->here; _e; _e = _cmp < 0 ? _e->hl._left : _e->right) \ 239 | { _o = _DTOBJ(_e, _lk); _k = _DTKEY(_o, _ky, _sz); \ 240 | if((_cmp = _DTCMP((dt), _key, _k, _dc, _cmpf, _sz)) == 0) \ 241 | break; \ 242 | } \ 243 | action (_e ? _o : (void*)0); \ 244 | } while(0) 245 | 246 | #define _DTSRCH(dt,obj,action) \ 247 | do { Dtlink_t* _e; void *_o, *_k, *_key; Dtdisc_t* _dc; \ 248 | int _ky, _sz, _lk, _cmp; Dtcompar_f _cmpf; \ 249 | _dc = (dt)->disc; _DTDSC(_dc, _ky, _sz, _lk, _cmpf); \ 250 | _key = _DTKEY(obj, _ky, _sz); \ 251 | for(_e = (dt)->data->here; _e; _e = _cmp < 0 ? _e->hl._left : _e->right) \ 252 | { _o = _DTOBJ(_e, _lk); _k = _DTKEY(_o, _ky, _sz); \ 253 | if((_cmp = _DTCMP((dt), _key, _k, _dc, _cmpf, _sz)) == 0) \ 254 | break; \ 255 | } \ 256 | action (_e ? _o : (void*)0); \ 257 | } while(0) 258 | 259 | #define DTTREEMATCH(dt,key,action) _DTMTCH(_DT(dt),(void*)(key),action) 260 | #define DTTREESEARCH(dt,obj,action) _DTSRCH(_DT(dt),(void*)(obj),action) 261 | 262 | #define dtvnext(d) (_DT(d)->view) 263 | #define dtvcount(d) (_DT(d)->nview) 264 | #define dtvhere(d) (_DT(d)->walk) 265 | 266 | #define dtlink(d,e) (((Dtlink_t*)(e))->right) 267 | #define dtobj(d,e) _DTOBJ((e), _DT(d)->disc->link) 268 | #define dtfinger(d) (_DT(d)->data->here ? dtobj((d),_DT(d)->data->here):(void*)(0)) 269 | 270 | #define dtfirst(d) (*(_DT(d)->searchf))((d),(void*)(0),DT_FIRST) 271 | #define dtnext(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_NEXT) 272 | #define dtleast(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_SEARCH|DT_NEXT) 273 | #define dtlast(d) (*(_DT(d)->searchf))((d),(void*)(0),DT_LAST) 274 | #define dtprev(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_PREV) 275 | #define dtmost(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_SEARCH|DT_PREV) 276 | #define dtsearch(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_SEARCH) 277 | #define dtmatch(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_MATCH) 278 | #define dtinsert(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_INSERT) 279 | #define dtappend(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_INSERT|DT_APPEND) 280 | #define dtdelete(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_DELETE) 281 | #define dtattach(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_ATTACH) 282 | #define dtdetach(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_DETACH) 283 | #define dtclear(d) (*(_DT(d)->searchf))((d),(void*)(0),DT_CLEAR) 284 | #define dtfound(d) (_DT(d)->type & DT_FOUND) 285 | 286 | #define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */ 287 | #define dtcharhash(h,c) (((unsigned int)(h) + (unsigned int)(c)) * DT_PRIME ) 288 | 289 | #ifdef __cplusplus 290 | } 291 | #endif 292 | 293 | #endif /* _CDT_H */ 294 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/cgraph.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef ATT_GRAPH_H 15 | #define ATT_GRAPH_H 16 | 17 | #include 18 | #include "cdt.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #ifndef FALSE 25 | #define FALSE (0) 26 | #endif 27 | #ifndef TRUE 28 | #define TRUE (!FALSE) 29 | #endif 30 | #ifndef NOT 31 | #define NOT(x) (!(x)) 32 | #endif 33 | #ifndef NIL 34 | #define NIL(type) ((type)0) 35 | #endif 36 | #define NILgraph NIL(Agraph_t*) 37 | #define NILnode NIL(Agnode_t*) 38 | #define NILedge NIL(Agedge_t*) 39 | #define NILsym NIL(Agsym_t*) 40 | 41 | typedef uint64_t IDTYPE; 42 | 43 | /* forward struct type declarations */ 44 | typedef struct Agtag_s Agtag_t; 45 | typedef struct Agobj_s Agobj_t; /* generic object header */ 46 | typedef struct Agraph_s Agraph_t; /* graph, subgraph (or hyperedge) */ 47 | typedef struct Agnode_s Agnode_t; /* node (atom) */ 48 | typedef struct Agedge_s Agedge_t; /* node pair */ 49 | typedef struct Agdesc_s Agdesc_t; /* graph descriptor */ 50 | typedef struct Agmemdisc_s Agmemdisc_t; /* memory allocator */ 51 | typedef struct Agiddisc_s Agiddisc_t; /* object ID allocator */ 52 | typedef struct Agiodisc_s Agiodisc_t; /* IO services */ 53 | typedef struct Agdisc_s Agdisc_t; /* union of client discipline methods */ 54 | typedef struct Agdstate_s Agdstate_t; /* client state (closures) */ 55 | typedef struct Agsym_s Agsym_t; /* string attribute descriptors */ 56 | typedef struct Agattr_s Agattr_t; /* string attribute container */ 57 | typedef struct Agcbdisc_s Agcbdisc_t; /* client event callbacks */ 58 | typedef struct Agcbstack_s Agcbstack_t; /* enclosing state for cbdisc */ 59 | typedef struct Agclos_s Agclos_t; /* common fields for graph/subgs */ 60 | typedef struct Agrec_s Agrec_t; /* generic runtime record */ 61 | typedef struct Agdatadict_s Agdatadict_t; /* set of dictionaries per graph */ 62 | typedef struct Agedgepair_s Agedgepair_t; /* the edge object */ 63 | typedef struct Agsubnode_s Agsubnode_t; 64 | 65 | /* Header of a user record. These records are attached by client programs 66 | dynamically at runtime. A unique string ID must be given to each record 67 | attached to the same object. Cgraph has functions to create, search for, 68 | and delete these records. The records are maintained in a circular list, 69 | with obj->data pointing somewhere in the list. The search function has 70 | an option to lock this pointer on a given record. The application must 71 | be written so only one such lock is outstanding at a time. */ 72 | 73 | struct Agrec_s { 74 | char *name; 75 | Agrec_t *next; 76 | /* following this would be any programmer-defined data */ 77 | }; 78 | 79 | /* Object tag for graphs, nodes, and edges. While there may be several structs 80 | for a given node or edges, there is only one unique ID (per main graph). */ 81 | struct Agtag_s { 82 | unsigned objtype:2; /* see literal tags below */ 83 | unsigned mtflock:1; /* move-to-front lock, see above */ 84 | unsigned attrwf:1; /* attrs written (parity, write.c) */ 85 | unsigned seq:(sizeof(unsigned) * 8 - 4); /* sequence no. */ 86 | IDTYPE id; /* client ID */ 87 | }; 88 | 89 | /* object tags */ 90 | #define AGRAPH 0 /* can't exceed 2 bits. see Agtag_t. */ 91 | #define AGNODE 1 92 | #define AGOUTEDGE 2 93 | #define AGINEDGE 3 /* (1 << 1) indicates an edge tag. */ 94 | #define AGEDGE AGOUTEDGE /* synonym in object kind args */ 95 | 96 | /* a generic graph/node/edge header */ 97 | struct Agobj_s { 98 | Agtag_t tag; 99 | Agrec_t *data; 100 | }; 101 | 102 | #define AGTAG(obj) (((Agobj_t*)(obj))->tag) 103 | #define AGTYPE(obj) (AGTAG(obj).objtype) 104 | #define AGID(obj) (AGTAG(obj).id) 105 | #define AGSEQ(obj) (AGTAG(obj).seq) 106 | #define AGATTRWF(obj) (AGTAG(obj).attrwf) 107 | #define AGDATA(obj) (((Agobj_t*)(obj))->data) 108 | 109 | /* This is the node struct allocated per graph (or subgraph). It resides 110 | in the n_dict of the graph. The node set is maintained by libdict, but 111 | transparently to libgraph callers. Every node may be given an optional 112 | string name at its time of creation, or it is permissible to pass NIL(char*) 113 | for the name. */ 114 | 115 | struct Agsubnode_s { /* the node-per-graph-or-subgraph record */ 116 | Dtlink_t seq_link; /* must be first */ 117 | Dtlink_t id_link; 118 | Agnode_t *node; /* the object */ 119 | Dtlink_t *in_id, *out_id; /* by node/ID for random access */ 120 | Dtlink_t *in_seq, *out_seq; /* by node/sequence for serial access */ 121 | }; 122 | 123 | struct Agnode_s { 124 | Agobj_t base; 125 | Agraph_t *root; 126 | Agsubnode_t mainsub; /* embedded for main graph */ 127 | }; 128 | 129 | struct Agedge_s { 130 | Agobj_t base; 131 | Dtlink_t id_link; /* main graph only */ 132 | Dtlink_t seq_link; 133 | Agnode_t *node; /* the endpoint node */ 134 | }; 135 | 136 | struct Agedgepair_s { 137 | Agedge_t out, in; 138 | }; 139 | 140 | struct Agdesc_s { /* graph descriptor */ 141 | unsigned directed:1; /* if edges are asymmetric */ 142 | unsigned strict:1; /* if multi-edges forbidden */ 143 | unsigned no_loop:1; /* if no loops */ 144 | unsigned maingraph:1; /* if this is the top level graph */ 145 | unsigned flatlock:1; /* if sets are flattened into lists in cdt */ 146 | unsigned no_write:1; /* if a temporary subgraph */ 147 | unsigned has_attrs:1; /* if string attr tables should be initialized */ 148 | unsigned has_cmpnd:1; /* if may contain collapsed nodes */ 149 | }; 150 | 151 | /* disciplines for external resources needed by libgraph */ 152 | 153 | struct Agmemdisc_s { /* memory allocator */ 154 | void *(*open) (Agdisc_t*); /* independent of other resources */ 155 | void *(*alloc) (void *state, size_t req); 156 | void *(*resize) (void *state, void *ptr, size_t old, size_t req); 157 | void (*free) (void *state, void *ptr); 158 | void (*close) (void *state); 159 | }; 160 | 161 | struct Agiddisc_s { /* object ID allocator */ 162 | void *(*open) (Agraph_t * g, Agdisc_t*); /* associated with a graph */ 163 | long (*map) (void *state, int objtype, char *str, IDTYPE *id, 164 | int createflag); 165 | long (*alloc) (void *state, int objtype, IDTYPE id); 166 | void (*free) (void *state, int objtype, IDTYPE id); 167 | char *(*print) (void *state, int objtype, IDTYPE id); 168 | void (*close) (void *state); 169 | void (*idregister) (void *state, int objtype, void *obj); 170 | }; 171 | 172 | struct Agiodisc_s { 173 | int (*afread) (void *chan, char *buf, int bufsize); 174 | int (*putstr) (void *chan, const char *str); 175 | int (*flush) (void *chan); /* sync */ 176 | /* error messages? */ 177 | }; 178 | 179 | struct Agdisc_s { /* user's discipline */ 180 | Agmemdisc_t *mem; 181 | Agiddisc_t *id; 182 | Agiodisc_t *io; 183 | }; 184 | 185 | /* default resource disciplines */ 186 | 187 | /*visual studio*/ 188 | #if defined(_MSC_VER) && !defined(CGRAPH_EXPORTS) 189 | #define extern __declspec(dllimport) 190 | #endif 191 | /*end visual studio*/ 192 | 193 | extern Agmemdisc_t AgMemDisc; 194 | extern Agiddisc_t AgIdDisc; 195 | extern Agiodisc_t AgIoDisc; 196 | 197 | extern Agdisc_t AgDefaultDisc; 198 | #undef extern 199 | 200 | struct Agdstate_s { 201 | void *mem; 202 | void *id; 203 | /* IO must be initialized and finalized outside Cgraph, 204 | * and channels (FILES) are passed as void* arguments. */ 205 | }; 206 | 207 | typedef void (*agobjfn_t) (Agraph_t * g, Agobj_t * obj, void *arg); 208 | typedef void (*agobjupdfn_t) (Agraph_t * g, Agobj_t * obj, void *arg, 209 | Agsym_t * sym); 210 | 211 | struct Agcbdisc_s { 212 | struct { 213 | agobjfn_t ins; 214 | agobjupdfn_t mod; 215 | agobjfn_t del; 216 | } graph, node, edge; 217 | }; 218 | 219 | struct Agcbstack_s { /* object event callbacks */ 220 | Agcbdisc_t *f; /* methods */ 221 | void *state; /* closure */ 222 | Agcbstack_t *prev; /* kept in a stack, unlike other disciplines */ 223 | }; 224 | 225 | struct Agclos_s { 226 | Agdisc_t disc; /* resource discipline functions */ 227 | Agdstate_t state; /* resource closures */ 228 | Dict_t *strdict; /* shared string dict */ 229 | uint64_t seq[3]; /* local object sequence number counter */ 230 | Agcbstack_t *cb; /* user and system callback function stacks */ 231 | unsigned char callbacks_enabled; /* issue user callbacks or hold them? */ 232 | Dict_t *lookup_by_name[3]; 233 | Dict_t *lookup_by_id[3]; 234 | }; 235 | 236 | struct Agraph_s { 237 | Agobj_t base; 238 | Agdesc_t desc; 239 | Dtlink_t link; 240 | Dict_t *n_seq; /* the node set in sequence */ 241 | Dict_t *n_id; /* the node set indexed by ID */ 242 | Dict_t *e_seq, *e_id; /* holders for edge sets */ 243 | Dict_t *g_dict; /* subgraphs - descendants */ 244 | Agraph_t *parent, *root; /* subgraphs - ancestors */ 245 | Agclos_t *clos; /* shared resources */ 246 | }; 247 | 248 | extern void agpushdisc(Agraph_t * g, Agcbdisc_t * disc, void *state); 249 | extern int agpopdisc(Agraph_t * g, Agcbdisc_t * disc); 250 | extern int agcallbacks(Agraph_t * g, int flag); /* return prev value */ 251 | 252 | /* graphs */ 253 | extern Agraph_t *agopen(char *name, Agdesc_t desc, Agdisc_t * disc); 254 | extern int agclose(Agraph_t * g); 255 | extern Agraph_t *agread(void *chan, Agdisc_t * disc); 256 | extern Agraph_t *agmemread(const char *cp); 257 | extern void agreadline(int); 258 | extern void agsetfile(char *); 259 | extern Agraph_t *agconcat(Agraph_t * g, void *chan, Agdisc_t * disc); 260 | extern int agwrite(Agraph_t * g, void *chan); 261 | extern int agisdirected(Agraph_t * g); 262 | extern int agisundirected(Agraph_t * g); 263 | extern int agisstrict(Agraph_t * g); 264 | extern int agissimple(Agraph_t * g); 265 | 266 | /* nodes */ 267 | extern Agnode_t *agnode(Agraph_t * g, char *name, int createflag); 268 | extern Agnode_t *agidnode(Agraph_t * g, IDTYPE id, int createflag); 269 | extern Agnode_t *agsubnode(Agraph_t * g, Agnode_t * n, int createflag); 270 | extern Agnode_t *agfstnode(Agraph_t * g); 271 | extern Agnode_t *agnxtnode(Agraph_t * g, Agnode_t * n); 272 | extern Agnode_t *aglstnode(Agraph_t * g); 273 | extern Agnode_t *agprvnode(Agraph_t * g, Agnode_t * n); 274 | 275 | extern Agsubnode_t *agsubrep(Agraph_t * g, Agnode_t * n); 276 | extern int agnodebefore(Agnode_t *u, Agnode_t *v); /* we have no shame */ 277 | 278 | /* edges */ 279 | extern Agedge_t *agedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, 280 | char *name, int createflag); 281 | extern Agedge_t *agidedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, 282 | IDTYPE id, int createflag); 283 | extern Agedge_t *agsubedge(Agraph_t * g, Agedge_t * e, int createflag); 284 | extern Agedge_t *agfstin(Agraph_t * g, Agnode_t * n); 285 | extern Agedge_t *agnxtin(Agraph_t * g, Agedge_t * e); 286 | extern Agedge_t *agfstout(Agraph_t * g, Agnode_t * n); 287 | extern Agedge_t *agnxtout(Agraph_t * g, Agedge_t * e); 288 | extern Agedge_t *agfstedge(Agraph_t * g, Agnode_t * n); 289 | extern Agedge_t *agnxtedge(Agraph_t * g, Agedge_t * e, Agnode_t * n); 290 | 291 | /* generic */ 292 | extern Agraph_t *agraphof(void* obj); 293 | extern Agraph_t *agroot(void* obj); 294 | extern int agcontains(Agraph_t *, void *); 295 | extern char *agnameof(void *); 296 | extern int agrelabel(void *obj, char *name); /* scary */ 297 | extern int agrelabel_node(Agnode_t * n, char *newname); 298 | extern int agdelete(Agraph_t * g, void *obj); 299 | extern long agdelsubg(Agraph_t * g, Agraph_t * sub); /* could be agclose */ 300 | extern int agdelnode(Agraph_t * g, Agnode_t * arg_n); 301 | extern int agdeledge(Agraph_t * g, Agedge_t * arg_e); 302 | extern int agobjkind(void *); 303 | 304 | /* strings */ 305 | extern char *agstrdup(Agraph_t *, char *); 306 | extern char *agstrdup_html(Agraph_t *, char *); 307 | extern int aghtmlstr(char *); 308 | extern char *agstrbind(Agraph_t * g, char *); 309 | extern int agstrfree(Agraph_t *, char *); 310 | extern char *agcanon(char *, int); 311 | extern char *agstrcanon(char *, char *); 312 | extern char *agcanonStr(char *str); /* manages its own buf */ 313 | 314 | /* definitions for dynamic string attributes */ 315 | struct Agattr_s { /* dynamic string attributes */ 316 | Agrec_t h; /* common data header */ 317 | Dict_t *dict; /* shared dict to interpret attr field */ 318 | char **str; /* the attribute string values */ 319 | }; 320 | 321 | struct Agsym_s { /* symbol in one of the above dictionaries */ 322 | Dtlink_t link; 323 | char *name; /* attribute's name */ 324 | char *defval; /* its default value for initialization */ 325 | int id; /* its index in attr[] */ 326 | unsigned char kind; /* referent object type */ 327 | unsigned char fixed; /* immutable value */ 328 | unsigned char print; /* always print */ 329 | }; 330 | 331 | struct Agdatadict_s { /* set of dictionaries per graph */ 332 | Agrec_t h; /* installed in list of graph recs */ 333 | struct { 334 | Dict_t *n, *e, *g; 335 | } dict; 336 | }; 337 | 338 | extern Agsym_t *agattr(Agraph_t * g, int kind, char *name, char *value); 339 | extern Agsym_t *agattrsym(void *obj, char *name); 340 | extern Agsym_t *agnxtattr(Agraph_t * g, int kind, Agsym_t * attr); 341 | extern int agcopyattr(void *oldobj, void *newobj); 342 | 343 | extern void *agbindrec(void *obj, char *name, unsigned int size, 344 | int move_to_front); 345 | extern Agrec_t *aggetrec(void *obj, char *name, int move_to_front); 346 | extern int agdelrec(void *obj, char *name); 347 | extern void aginit(Agraph_t * g, int kind, char *rec_name, int rec_size, 348 | int move_to_front); 349 | extern void agclean(Agraph_t * g, int kind, char *rec_name); 350 | 351 | extern char *agget(void *obj, char *name); 352 | extern char *agxget(void *obj, Agsym_t * sym); 353 | extern int agset(void *obj, char *name, char *value); 354 | extern int agxset(void *obj, Agsym_t * sym, char *value); 355 | extern int agsafeset(void* obj, char* name, char* value, char* def); 356 | 357 | /* defintions for subgraphs */ 358 | extern Agraph_t *agsubg(Agraph_t * g, char *name, int cflag); /* constructor */ 359 | extern Agraph_t *agidsubg(Agraph_t * g, IDTYPE id, int cflag); /* constructor */ 360 | extern Agraph_t *agfstsubg(Agraph_t * g), *agnxtsubg(Agraph_t * subg); 361 | extern Agraph_t *agparent(Agraph_t * g); 362 | 363 | /* set cardinality */ 364 | extern int agnnodes(Agraph_t * g), agnedges(Agraph_t * g), agnsubg(Agraph_t * g); 365 | extern int agdegree(Agraph_t * g, Agnode_t * n, int in, int out); 366 | extern int agcountuniqedges(Agraph_t * g, Agnode_t * n, int in, int out); 367 | 368 | /* memory */ 369 | extern void *agalloc(Agraph_t * g, size_t size); 370 | extern void *agrealloc(Agraph_t * g, void *ptr, size_t oldsize, 371 | size_t size); 372 | extern void agfree(Agraph_t * g, void *ptr); 373 | extern struct _vmalloc_s *agheap(Agraph_t * g); 374 | 375 | /* an engineering compromise is a joy forever */ 376 | extern void aginternalmapclearlocalnames(Agraph_t * g); 377 | 378 | #define agnew(g,t) ((t*)agalloc(g,sizeof(t))) 379 | #define agnnew(g,n,t) ((t*)agalloc(g,(n)*sizeof(t))) 380 | 381 | /* error handling */ 382 | typedef enum { AGWARN, AGERR, AGMAX, AGPREV } agerrlevel_t; 383 | typedef int (*agusererrf) (char*); 384 | extern agerrlevel_t agseterr(agerrlevel_t); 385 | extern char *aglasterr(void); 386 | extern int agerr(agerrlevel_t level, const char *fmt, ...); 387 | extern void agerrorf(const char *fmt, ...); 388 | extern void agwarningf(const char *fmt, ...); 389 | extern int agerrors(void); 390 | extern int agreseterrors(void); 391 | extern agusererrf agseterrf(agusererrf); 392 | 393 | /* data access macros */ 394 | /* this assumes that e[0] is out and e[1] is inedge, see edgepair in edge.c */ 395 | #define AGIN2OUT(e) ((e)-1) 396 | #define AGOUT2IN(e) ((e)+1) 397 | #define AGOPP(e) ((AGTYPE(e)==AGINEDGE)?AGIN2OUT(e):AGOUT2IN(e)) 398 | #define AGMKOUT(e) (AGTYPE(e) == AGOUTEDGE? (e): AGIN2OUT(e)) 399 | #define AGMKIN(e) (AGTYPE(e) == AGINEDGE? (e): AGOUT2IN(e)) 400 | #define AGTAIL(e) (AGMKIN(e)->node) 401 | #define AGHEAD(e) (AGMKOUT(e)->node) 402 | #define agtail(e) AGTAIL(e) 403 | #define aghead(e) AGHEAD(e) 404 | #define agopp(e) AGOPP(e) 405 | #define ageqedge(e,f) (AGMKOUT(e) == AGMKOUT(f)) 406 | 407 | #define TAILPORT_ID "tailport" 408 | #define HEADPORT_ID "headport" 409 | 410 | #if defined(_MSC_VER) && !defined(CGRAPH_EXPORTS) 411 | #define extern __declspec(dllimport) 412 | #endif 413 | 414 | extern Agdesc_t Agdirected, Agstrictdirected, Agundirected, 415 | Agstrictundirected; 416 | 417 | #undef extern 418 | 419 | /* fast graphs */ 420 | void agflatten(Agraph_t * g, int flag); 421 | typedef Agsubnode_t Agnoderef_t; 422 | typedef Dtlink_t Agedgeref_t; 423 | 424 | #define AGHEADPOINTER(g) ((Agnoderef_t*)(g->n_seq->data->hh._head)) 425 | #define AGRIGHTPOINTER(rep) ((Agnoderef_t*)((rep)->seq_link.right?((void*)((rep)->seq_link.right) - offsetof(Agsubnode_t,seq_link)):0)) 426 | #define AGLEFTPOINTER(rep) ((Agnoderef_t*)((rep)->seq_link.hl._left?((void*)((rep)->seq_link.hl._left) - offsetof(Agsubnode_t,seq_link)):0)) 427 | 428 | #define FIRSTNREF(g) (agflatten(g,1), AGHEADPOINTER(g)) 429 | 430 | #define NEXTNREF(g,rep) (AGRIGHTPOINTER(rep) == AGHEADPOINTER(g)?0:AGRIGHTPOINTER(rep)) 431 | 432 | #define PREVNREF(g,rep) (((rep)==AGHEADPOINTER(g))?0:(AGLEFTPOINTER(rep))) 433 | 434 | #define LASTNREF(g) (agflatten(g,1), AGHEADPOINTER(g)?AGLEFTPOINTER(AGHEADPOINTER(g)):0) 435 | #define NODEOF(rep) ((rep)->node) 436 | 437 | #define FIRSTOUTREF(g,sn) (agflatten(g,1), (sn)->out_seq) 438 | #define LASTOUTREF(g,sn) (agflatten(g,1), (Agedgeref_t*)dtlast(sn->out_seq)) 439 | #define FIRSTINREF(g,sn) (agflatten(g,1), (sn)->in_seq) 440 | #define NEXTEREF(g,rep) ((rep)->right) 441 | #define PREVEREF(g,rep) ((rep)->hl._left) 442 | /* this is expedient but a bit slimey because it "knows" that dict entries of both nodes 443 | and edges are embedded in main graph objects but allocated separately in subgraphs */ 444 | #define AGSNMAIN(sn) ((sn)==(&((sn)->node->mainsub))) 445 | #define EDGEOF(sn,rep) (AGSNMAIN(sn)?((Agedge_t*)((unsigned char*)(rep) - offsetof(Agedge_t,seq_link))) : ((Dthold_t*)(rep))->obj) 446 | 447 | #undef extern 448 | 449 | #ifdef __cplusplus 450 | } 451 | #endif 452 | #endif 453 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/color.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GV_COLOR_H 15 | #define GV_COLOR_H 16 | 17 | /* #include "arith.h" */ 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | typedef struct hsvrgbacolor_t { 24 | char *name; 25 | unsigned char h, s, v; 26 | unsigned char r, g, b, a; 27 | } hsvrgbacolor_t; 28 | 29 | /* possible representations of color in gvcolor_t */ 30 | typedef enum { HSVA_DOUBLE, RGBA_BYTE, RGBA_WORD, CMYK_BYTE, 31 | RGBA_DOUBLE, COLOR_STRING, COLOR_INDEX } color_type_t; 32 | 33 | /* gvcolor_t can hold a color spec in a choice or representations */ 34 | typedef struct color_s { 35 | union { 36 | double RGBA[4]; 37 | double HSVA[4]; 38 | unsigned char rgba[4]; 39 | unsigned char cmyk[4]; 40 | int rrggbbaa[4]; 41 | char *string; 42 | int index; 43 | } u; 44 | color_type_t type; 45 | } gvcolor_t; 46 | 47 | #define COLOR_MALLOC_FAIL -1 48 | #define COLOR_UNKNOWN 1 49 | #define COLOR_OK 0 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | #endif 55 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/geom.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | /* geometric types and macros (e.g. points and boxes) with application to, but 15 | * no specific dependance on graphs */ 16 | 17 | #ifndef GV_GEOM_H 18 | #define GV_GEOM_H 19 | 20 | #include "arith.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct { int x, y; } point; 27 | 28 | typedef struct pointf_s { double x, y; } pointf; 29 | 30 | /* tell pathplan/pathgeom.h */ 31 | #define HAVE_POINTF_S 32 | 33 | typedef struct { point LL, UR; } box; 34 | 35 | typedef struct { pointf LL, UR; } boxf; 36 | 37 | 38 | /* true if point p is inside box b */ 39 | #define INSIDE(p,b) (BETWEEN((b).LL.x,(p).x,(b).UR.x) && BETWEEN((b).LL.y,(p).y,(b).UR.y)) 40 | 41 | /* true if boxes b0 and b1 overlap */ 42 | #define OVERLAP(b0,b1) (((b0).UR.x >= (b1).LL.x) && ((b1).UR.x >= (b0).LL.x) && ((b0).UR.y >= (b1).LL.y) && ((b1).UR.y >= (b0).LL.y)) 43 | 44 | /* true if box b0 completely contains b1*/ 45 | #define CONTAINS(b0,b1) (((b0).UR.x >= (b1).UR.x) && ((b0).UR.y >= (b1).UR.y) && ((b0).LL.x <= (b1).LL.x) && ((b0).LL.y <= (b1).LL.y)) 46 | 47 | /* expand box b as needed to enclose point p */ 48 | #define EXPANDBP(b, p) ((b).LL.x = MIN((b).LL.x, (p).x), (b).LL.y = MIN((b).LL.y, (p).y), (b).UR.x = MAX((b).UR.x, (p).x), (b).UR.y = MAX((b).UR.y, (p).y)) 49 | 50 | /* expand box b0 as needed to enclose box b1 */ 51 | #define EXPANDBB(b0, b1) ((b0).LL.x = MIN((b0).LL.x, (b1).LL.x), (b0).LL.y = MIN((b0).LL.y, (b1).LL.y), (b0).UR.x = MAX((b0).UR.x, (b1).UR.x), (b0).UR.y = MAX((b0).UR.y, (b1).UR.y)) 52 | 53 | /* clip box b0 to fit box b1 */ 54 | #define CLIPBB(b0, b1) ((b0).LL.x = MAX((b0).LL.x, (b1).LL.x), (b0).LL.y = MAX((b0).LL.y, (b1).LL.y), (b0).UR.x = MIN((b0).UR.x, (b1).UR.x), (b0).UR.y = MIN((b0).UR.y, (b1).UR.y)) 55 | 56 | #define LEN2(a,b) (SQR(a) + SQR(b)) 57 | #define LEN(a,b) (sqrt(LEN2((a),(b)))) 58 | 59 | #define DIST2(p,q) (LEN2(((p).x - (q).x),((p).y - (q).y))) 60 | #define DIST(p,q) (sqrt(DIST2((p),(q)))) 61 | 62 | #define POINTS_PER_INCH 72 63 | #define POINTS_PER_PC ((double)POINTS_PER_INCH / 6) 64 | #define POINTS_PER_CM ((double)POINTS_PER_INCH * 0.393700787) 65 | #define POINTS_PER_MM ((double)POINTS_PER_INCH * 0.0393700787) 66 | 67 | #define POINTS(a_inches) (ROUND((a_inches)*POINTS_PER_INCH)) 68 | #define INCH2PS(a_inches) ((a_inches)*(double)POINTS_PER_INCH) 69 | #define PS2INCH(a_points) ((a_points)/(double)POINTS_PER_INCH) 70 | 71 | #define P2PF(p,pf) ((pf).x = (p).x,(pf).y = (p).y) 72 | #define PF2P(pf,p) ((p).x = ROUND((pf).x),(p).y = ROUND((pf).y)) 73 | 74 | #define B2BF(b,bf) (P2PF((b).LL,(bf).LL),P2PF((b).UR,(bf).UR)) 75 | #define BF2B(bf,b) (PF2P((bf).LL,(b).LL),PF2P((bf).UR,(b).UR)) 76 | 77 | #define APPROXEQ(a,b,tol) (ABS((a) - (b)) < (tol)) 78 | #define APPROXEQPT(p,q,tol) (DIST2((p),(q)) < SQR(tol)) 79 | 80 | /* some common tolerance values */ 81 | #define MILLIPOINT .001 82 | #define MICROPOINT .000001 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/graphviz_version.h: -------------------------------------------------------------------------------- 1 | #define GVPLUGIN_CONFIG_FILE "config6" 2 | #define GVPLUGIN_VERSION 6 3 | #define PACKAGE_BUGREPORT "http://www.graphviz.org/" 4 | #define PACKAGE_NAME "graphviz" 5 | #define PACKAGE_STRING "graphviz 2.40.1" 6 | #define PACKAGE_TARNAME "graphviz" 7 | #define PACKAGE_URL "" 8 | #define PACKAGE_VERSION "2.40.1" 9 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvc.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVC_H 15 | #define GVC_H 16 | 17 | #include "types.h" 18 | #include "gvplugin.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #ifdef GVDLL 25 | #define extern __declspec(dllexport) 26 | #else 27 | #define extern 28 | #endif 29 | 30 | /*visual studio*/ 31 | #ifdef WIN32 32 | #ifndef GVC_EXPORTS 33 | #undef extern 34 | #define extern __declspec(dllimport) 35 | #endif 36 | #endif 37 | /*end visual studio*/ 38 | 39 | #define LAYOUT_DONE(g) (agbindrec(g, "Agraphinfo_t", 0, TRUE) && GD_drawing(g)) 40 | 41 | /* misc */ 42 | /* FIXME - this needs eliminating or renaming */ 43 | extern void gvToggle(int); 44 | 45 | /* set up a graphviz context */ 46 | extern GVC_t *gvNEWcontext(const lt_symlist_t *builtins, int demand_loading); 47 | 48 | /* set up a graphviz context - and init graph - retaining old API */ 49 | extern GVC_t *gvContext(void); 50 | /* set up a graphviz context - and init graph - with builtins */ 51 | extern GVC_t *gvContextPlugins(const lt_symlist_t *builtins, int demand_loading); 52 | 53 | /* get information associated with a graphviz context */ 54 | extern char **gvcInfo(GVC_t*); 55 | extern char *gvcVersion(GVC_t*); 56 | extern char *gvcBuildDate(GVC_t*); 57 | 58 | /* parse command line args - minimally argv[0] sets layout engine */ 59 | extern int gvParseArgs(GVC_t *gvc, int argc, char **argv); 60 | extern graph_t *gvNextInputGraph(GVC_t *gvc); 61 | extern graph_t *gvPluginsGraph(GVC_t *gvc); 62 | 63 | /* Compute a layout using a specified engine */ 64 | extern int gvLayout(GVC_t *gvc, graph_t *g, const char *engine); 65 | 66 | /* Compute a layout using layout engine from command line args */ 67 | extern int gvLayoutJobs(GVC_t *gvc, graph_t *g); 68 | 69 | /* Render layout into string attributes of the graph */ 70 | extern void attach_attrs(graph_t *g); 71 | 72 | /* Render layout in a specified format to an open FILE */ 73 | extern int gvRender(GVC_t *gvc, graph_t *g, const char *format, FILE *out); 74 | 75 | /* Render layout in a specified format to a file with the given name */ 76 | extern int gvRenderFilename(GVC_t *gvc, graph_t *g, const char *format, const char *filename); 77 | 78 | /* Render layout in a specified format to an external context */ 79 | extern int gvRenderContext(GVC_t *gvc, graph_t *g, const char *format, void *context); 80 | 81 | /* Render layout in a specified format to a malloc'ed string */ 82 | extern int gvRenderData(GVC_t *gvc, graph_t *g, const char *format, char **result, unsigned int *length); 83 | 84 | /* Free memory allocated and pointed to by *result in gvRenderData */ 85 | extern void gvFreeRenderData (char* data); 86 | 87 | /* Render layout according to -T and -o options found by gvParseArgs */ 88 | extern int gvRenderJobs(GVC_t *gvc, graph_t *g); 89 | 90 | /* Clean up layout data structures - layouts are not nestable (yet) */ 91 | extern int gvFreeLayout(GVC_t *gvc, graph_t *g); 92 | 93 | /* Clean up graphviz context */ 94 | extern void gvFinalize(GVC_t *gvc); 95 | extern int gvFreeContext(GVC_t *gvc); 96 | 97 | /* Return list of plugins of type kind. 98 | * kind would normally be "render" "layout" "textlayout" "device" "loadimage" 99 | * The size of the list is stored in sz. 100 | * The caller is responsible for freeing the storage. This involves 101 | * freeing each item, then the list. 102 | * Returns NULL on error, or if there are no plugins. 103 | * In the former case, sz is unchanged; in the latter, sz = 0. 104 | * 105 | * At present, the str argument is unused, but may be used to modify 106 | * the search as in gvplugin_list above. 107 | */ 108 | extern char** gvPluginList (GVC_t *gvc, const char* kind, int* sz, char*); 109 | 110 | /** Add a library from your user application 111 | * @param gvc Graphviz context to add library to 112 | * @param lib library to add 113 | */ 114 | extern void gvAddLibrary(GVC_t *gvc, gvplugin_library_t *lib); 115 | 116 | /** Perform a Transitive Reduction on a graph 117 | * @param g graph to be transformed. 118 | */ 119 | extern int gvToolTred(graph_t *g); 120 | 121 | #undef extern 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif /* GVC_H */ 128 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvcext.h: -------------------------------------------------------------------------------- 1 | 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | /* Common header used by both clients and plugins */ 15 | 16 | #ifndef GVCEXT_H 17 | #define GVCEXT_H 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* 24 | * Define an apis array of name strings using an enumerated api_t as index. 25 | * The enumerated type is defined here. The apis array is 26 | * inititialized in gvplugin.c by redefining ELEM and reinvoking APIS. 27 | */ 28 | #define APIS ELEM(render) ELEM(layout) ELEM(textlayout) ELEM(device) ELEM(loadimage) 29 | 30 | /* 31 | * Define api_t using names based on the plugin names with API_ prefixed. 32 | */ 33 | #define ELEM(x) API_##x, 34 | typedef enum { APIS _DUMMY_ELEM_=0 } api_t; /* API_render, API_layout, ... */ 35 | /* Stupid but true: The sole purpose of "_DUMMY_ELEM_=0" 36 | * is to avoid a "," after the last element of the enum 37 | * because some compilers when using "-pedantic" 38 | * generate an error for about the dangling "," 39 | * but only if this header is used from a .cpp file! 40 | * Setting it to 0 makes sure that the enumeration 41 | * does not define an extra value. (It does however 42 | * define _DUMMY_ELEM_ as an enumeration symbol, 43 | * but its value duplicates that of the first 44 | * symbol in the enumeration - in this case "render".) 45 | */ 46 | 47 | /* One could wonder why trailing "," in: 48 | * int nums[]={1,2,3,}; 49 | * is OK, but in: 50 | * typedef enum {a,b,c,} abc_t; 51 | * is not!!! 52 | */ 53 | #undef ELEM 54 | 55 | typedef struct GVJ_s GVJ_t; 56 | typedef struct GVG_s GVG_t; 57 | typedef struct GVC_s GVC_t; 58 | 59 | typedef struct { 60 | const char *name; 61 | void* address; 62 | } lt_symlist_t; 63 | 64 | typedef struct gvplugin_available_s gvplugin_available_t; 65 | 66 | /*visual studio*/ 67 | #ifdef WIN32 68 | #ifndef GVC_EXPORTS 69 | __declspec(dllimport) lt_symlist_t lt_preloaded_symbols[]; 70 | #else 71 | //__declspec(dllexport) lt_symlist_t lt_preloaded_symbols[]; 72 | #if !defined(LTDL_H) 73 | lt_symlist_t lt_preloaded_symbols[]; 74 | #endif 75 | #endif 76 | #endif 77 | /*end visual studio*/ 78 | 79 | 80 | #ifndef WIN32 81 | #if defined(GVDLL) 82 | __declspec(dllexport) lt_symlist_t lt_preloaded_symbols[]; 83 | #else 84 | #if !defined(LTDL_H) 85 | extern lt_symlist_t lt_preloaded_symbols[]; 86 | #endif 87 | #endif 88 | #endif 89 | 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | 95 | 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvcjob.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | /* Common header used by both clients and plugins */ 15 | 16 | #ifndef GVCJOB_H 17 | #define GVCJOB_H 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #include "gvcommon.h" 24 | #include "color.h" 25 | 26 | #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0])) 27 | 28 | typedef struct gvdevice_engine_s gvdevice_engine_t; 29 | typedef struct gvformatter_engine_s gvformatter_engine_t; 30 | typedef struct gvrender_engine_s gvrender_engine_t; 31 | typedef struct gvlayout_engine_s gvlayout_engine_t; 32 | typedef struct gvtextlayout_engine_s gvtextlayout_engine_t; 33 | typedef struct gvloadimage_engine_s gvloadimage_engine_t; 34 | 35 | typedef enum { PEN_NONE, PEN_DASHED, PEN_DOTTED, PEN_SOLID } pen_type; 36 | typedef enum { FILL_NONE, FILL_SOLID, FILL_LINEAR, FILL_RADIAL } fill_type; 37 | typedef enum { FONT_REGULAR, FONT_BOLD, FONT_ITALIC } font_type; 38 | typedef enum { LABEL_PLAIN, LABEL_HTML } label_type; 39 | 40 | #define PENWIDTH_NORMAL 1. 41 | #define PENWIDTH_BOLD 2. 42 | typedef enum { GVATTR_STRING, GVATTR_BOOL, GVATTR_COLOR } gvattr_t; 43 | 44 | /* The -T output formats listed below are examples only, they are not definitive or inclusive, 45 | other outputs may use the flags now, or in the future 46 | 47 | Default emit order is breadth first graph walk order 48 | EMIT_SORTED emits nodes before edges 49 | EMIT_COLORS emits colors before nodes or edge -Tfig 50 | EMIT_CLUSTERS_LAST emits cluster after nodes and edges 51 | EMIT_PREORDER emit in preorder traversal ??? 52 | EMIT_EDGE_SORTED emits edges before nodes 53 | 54 | GVDEVICE_DOES_PAGES provides pagination support -Tps 55 | GVDEVICE_DOES_LAYERS provides support for layers -Tps 56 | GVDEVICE_EVENTS supports mouse events -Tgtk, -Txlib 57 | GVDEVICE_DOES_TRUECOLOR supports alpha channel -Tpng, -Tgtk, -Txlib 58 | GVDEVICE_BINARY_FORMAT Suppresses \r\n substitution for linends 59 | GVDEVICE_COMPRESSED_FORMAT controls libz compression 60 | GVDEVICE_NO_WRITER used when gvdevice is not used because device uses its own writer, -Tming, devil outputs (FIXME seems to overlap OUTPUT_NOT_REQUIRED) 61 | 62 | GVRENDER_Y_GOES_DOWN device origin top left, y goes down, otherwise 63 | device origin lower left, y goes up 64 | GVRENDER_DOES_TRANSFORM device uses scale, translate, rotate to do its own 65 | coordinate transformations, otherwise coordinates 66 | are pre-transformed 67 | GVRENDER_DOES_ARROWS renderer has its own idea of arrow shapes (deprecated) 68 | GVRENDER_DOES_LABELS basically, maps don't need labels 69 | GVRENDER_DOES_MAPS renderer encodes mapping information for mouse events -Tcmapx -Tsvg 70 | GVRENDER_DOES_MAP_RECTANGLE supports a 2 coord rectngle optimization 71 | GVRENDER_DOES_MAP_CIRCLE supports a 1 coord + radius circle optimization 72 | GVRENDER_DOES_MAP_POLYGON supports polygons (basically, -Tsvg uses anchors, so doesn't need to support any map shapes) 73 | GVRENDER_DOES_MAP_ELLIPSE supports a 2 coord ellipse optimization 74 | GVRENDER_DOES_MAP_BSPLINE supports mapping of splines 75 | GVRENDER_DOES_TOOLTIPS can represent tooltip info -Tcmapx, -Tsvg 76 | GVRENDER_DOES_TARGETS can represent target info (open link in a new tab or window) 77 | GVRENDER_DOES_Z render support 2.5D representation -Tvrml 78 | GVRENDER_NO_WHITE_BG don't paint white background, assumes white paper -Tps 79 | LAYOUT_NOT_REQUIRED don't perform layout -Tcanon 80 | OUTPUT_NOT_REQUIRED don't use gvdevice for output (basically when agwrite() used instead) -Tcanon, -Txdot 81 | */ 82 | 83 | 84 | #define EMIT_SORTED (1<<0) 85 | #define EMIT_COLORS (1<<1) 86 | #define EMIT_CLUSTERS_LAST (1<<2) 87 | #define EMIT_PREORDER (1<<3) 88 | #define EMIT_EDGE_SORTED (1<<4) 89 | #define GVDEVICE_DOES_PAGES (1<<5) 90 | #define GVDEVICE_DOES_LAYERS (1<<6) 91 | #define GVDEVICE_EVENTS (1<<7) 92 | #define GVDEVICE_DOES_TRUECOLOR (1<<8) 93 | #define GVDEVICE_BINARY_FORMAT (1<<9) 94 | #define GVDEVICE_COMPRESSED_FORMAT (1<<10) 95 | #define GVDEVICE_NO_WRITER (1<<11) 96 | #define GVRENDER_Y_GOES_DOWN (1<<12) 97 | #define GVRENDER_DOES_TRANSFORM (1<<13) 98 | #define GVRENDER_DOES_ARROWS (1<<14) 99 | #define GVRENDER_DOES_LABELS (1<<15) 100 | #define GVRENDER_DOES_MAPS (1<<16) 101 | #define GVRENDER_DOES_MAP_RECTANGLE (1<<17) 102 | #define GVRENDER_DOES_MAP_CIRCLE (1<<18) 103 | #define GVRENDER_DOES_MAP_POLYGON (1<<19) 104 | #define GVRENDER_DOES_MAP_ELLIPSE (1<<20) 105 | #define GVRENDER_DOES_MAP_BSPLINE (1<<21) 106 | #define GVRENDER_DOES_TOOLTIPS (1<<22) 107 | #define GVRENDER_DOES_TARGETS (1<<23) 108 | #define GVRENDER_DOES_Z (1<<24) 109 | #define GVRENDER_NO_WHITE_BG (1<<25) 110 | #define LAYOUT_NOT_REQUIRED (1<<26) 111 | #define OUTPUT_NOT_REQUIRED (1<<27) 112 | 113 | typedef struct { 114 | int flags; 115 | double default_pad; /* graph units */ 116 | char **knowncolors; 117 | int sz_knowncolors; 118 | color_type_t color_type; 119 | } gvrender_features_t; 120 | 121 | typedef struct { 122 | int flags; 123 | pointf default_margin; /* left/right, top/bottom - points */ 124 | pointf default_pagesize;/* default page width, height - points */ 125 | pointf default_dpi; 126 | } gvdevice_features_t; 127 | 128 | #define LAYOUT_USES_RANKDIR (1<<0) 129 | 130 | typedef struct gvplugin_active_device_s { 131 | gvdevice_engine_t *engine; 132 | int id; 133 | gvdevice_features_t *features; 134 | const char *type; 135 | } gvplugin_active_device_t; 136 | 137 | typedef struct gvplugin_active_render_s { 138 | gvrender_engine_t *engine; 139 | int id; 140 | gvrender_features_t *features; 141 | const char *type; 142 | } gvplugin_active_render_t; 143 | 144 | typedef struct gvplugin_active_loadimage_t { 145 | gvloadimage_engine_t *engine; 146 | int id; 147 | const char *type; 148 | } gvplugin_active_loadimage_t; 149 | 150 | typedef struct gv_argvlist_s { 151 | char **argv; 152 | int argc; 153 | int alloc; 154 | } gv_argvlist_t; 155 | 156 | typedef struct gvdevice_callbacks_s { 157 | void (*refresh) (GVJ_t * job); 158 | void (*button_press) (GVJ_t * job, int button, pointf pointer); 159 | void (*button_release) (GVJ_t * job, int button, pointf pointer); 160 | void (*motion) (GVJ_t * job, pointf pointer); 161 | void (*modify) (GVJ_t * job, const char *name, const char *value); 162 | void (*del) (GVJ_t * job); /* can't use "delete" 'cos C++ stole it */ 163 | void (*read) (GVJ_t * job, const char *filename, const char *layout); 164 | void (*layout) (GVJ_t * job, const char *layout); 165 | void (*render) (GVJ_t * job, const char *format, const char *filename); 166 | } gvdevice_callbacks_t; 167 | 168 | typedef int (*gvevent_key_callback_t) (GVJ_t * job); 169 | 170 | typedef struct gvevent_key_binding_s { 171 | char *keystring; 172 | gvevent_key_callback_t callback; 173 | } gvevent_key_binding_t; 174 | 175 | typedef enum {MAP_RECTANGLE, MAP_CIRCLE, MAP_POLYGON, } map_shape_t; 176 | 177 | typedef enum {ROOTGRAPH_OBJTYPE, CLUSTER_OBJTYPE, NODE_OBJTYPE, EDGE_OBJTYPE} obj_type; 178 | 179 | /* If this enum is changed, the implementation of xbuf and xbufs in 180 | * gvrender_core_dot.c will probably need to be changed. 181 | */ 182 | typedef enum { 183 | EMIT_GDRAW, EMIT_CDRAW, EMIT_TDRAW, EMIT_HDRAW, 184 | EMIT_GLABEL, EMIT_CLABEL, EMIT_TLABEL, EMIT_HLABEL, 185 | EMIT_NDRAW, EMIT_EDRAW, EMIT_NLABEL, EMIT_ELABEL, 186 | } emit_state_t; 187 | 188 | typedef struct obj_state_s obj_state_t; 189 | 190 | struct obj_state_s { 191 | obj_state_t *parent; 192 | 193 | obj_type type; 194 | union { 195 | graph_t *g; 196 | graph_t *sg; 197 | node_t *n; 198 | edge_t *e; 199 | } u; 200 | 201 | emit_state_t emit_state; 202 | 203 | gvcolor_t pencolor, fillcolor, stopcolor; 204 | int gradient_angle; 205 | float gradient_frac; 206 | pen_type pen; 207 | fill_type fill; 208 | double penwidth; 209 | char **rawstyle; 210 | 211 | double z, tail_z, head_z; /* z depths for 2.5D renderers such as vrml */ 212 | 213 | /* fully substituted text strings */ 214 | char *label; 215 | char *xlabel; 216 | char *taillabel; 217 | char *headlabel; 218 | 219 | char *url; /* if GVRENDER_DOES_MAPS */ 220 | char *id; 221 | char *labelurl; 222 | char *tailurl; 223 | char *headurl; 224 | 225 | char *tooltip; /* if GVRENDER_DOES_TOOLTIPS */ 226 | char *labeltooltip; 227 | char *tailtooltip; 228 | char *headtooltip; 229 | 230 | char *target; /* if GVRENDER_DOES_TARGETS */ 231 | char *labeltarget; 232 | char *tailtarget; 233 | char *headtarget; 234 | 235 | int explicit_tooltip:1; 236 | int explicit_tailtooltip:1; 237 | int explicit_headtooltip:1; 238 | int explicit_labeltooltip:1; 239 | int explicit_tailtarget:1; 240 | int explicit_headtarget:1; 241 | int explicit_edgetarget:1; 242 | int explicit_tailurl:1; 243 | int explicit_headurl:1; 244 | int labeledgealigned:1; 245 | 246 | /* primary mapped region - node shape, edge labels */ 247 | map_shape_t url_map_shape; 248 | int url_map_n; /* number of points for url map if GVRENDER_DOES_MAPS */ 249 | pointf *url_map_p; 250 | 251 | /* additonal mapped regions for edges */ 252 | int url_bsplinemap_poly_n; /* number of polygons in url bspline map 253 | if GVRENDER_DOES_MAPS && GVRENDER_DOES_MAP_BSPLINES */ 254 | int *url_bsplinemap_n; /* array of url_bsplinemap_poly_n ints 255 | of number of points in each polygon */ 256 | pointf *url_bsplinemap_p; /* all the polygon points */ 257 | 258 | int tailendurl_map_n; /* tail end intersection with node */ 259 | pointf *tailendurl_map_p; 260 | 261 | int headendurl_map_n; /* head end intersection with node */ 262 | pointf *headendurl_map_p; 263 | }; 264 | 265 | /* Note on units: 266 | * points - a physical distance (1/72 inch) unaffected by zoom or dpi. 267 | * graph units - related to physical distance by zoom. Equals points at zoom=1 268 | * device units - related to physical distance in points by dpi/72 269 | */ 270 | 271 | struct GVJ_s { 272 | GVC_t *gvc; /* parent gvc */ 273 | GVJ_t *next; /* linked list of jobs */ 274 | GVJ_t *next_active; /* linked list of active jobs (e.g. multiple windows) */ 275 | 276 | GVCOMMON_t *common; 277 | 278 | obj_state_t *obj; /* objects can be nested (at least clusters can) 279 | so keep object state on a stack */ 280 | char *input_filename; 281 | int graph_index; 282 | 283 | const char *layout_type; 284 | 285 | const char *output_filename; 286 | FILE *output_file; 287 | char *output_data; 288 | unsigned int output_data_allocated; 289 | unsigned int output_data_position; 290 | 291 | const char *output_langname; 292 | int output_lang; 293 | 294 | gvplugin_active_render_t render; 295 | gvplugin_active_device_t device; 296 | gvplugin_active_loadimage_t loadimage; 297 | gvdevice_callbacks_t *callbacks; 298 | pointf device_dpi; 299 | boolean device_sets_dpi; 300 | 301 | void *display; 302 | int screen; 303 | 304 | void *context; /* gd or cairo surface */ 305 | boolean external_context; /* context belongs to caller */ 306 | char *imagedata; /* location of imagedata */ 307 | 308 | int flags; /* emit_graph flags */ 309 | 310 | int numLayers; /* number of layers */ 311 | int layerNum; /* current layer - 1 based*/ 312 | 313 | point pagesArraySize; /* 2D size of page array */ 314 | point pagesArrayFirst;/* 2D starting corner in */ 315 | point pagesArrayMajor;/* 2D major increment */ 316 | point pagesArrayMinor;/* 2D minor increment */ 317 | point pagesArrayElem; /* 2D coord of current page - 0,0 based */ 318 | int numPages; /* number of pages */ 319 | 320 | boxf bb; /* graph bb with padding - graph units */ 321 | pointf pad; /* padding around bb - graph units */ 322 | boxf clip; /* clip region in graph units */ 323 | boxf pageBox; /* current page in graph units */ 324 | pointf pageSize; /* page size in graph units */ 325 | pointf focus; /* viewport focus - graph units */ 326 | 327 | double zoom; /* viewport zoom factor (points per graph unit) */ 328 | int rotation; /* viewport rotation (degrees) 0=portrait, 90=landscape */ 329 | 330 | pointf view; /* viewport size - points */ 331 | boxf canvasBox; /* viewport area - points */ 332 | pointf margin; /* job-specific margin - points */ 333 | 334 | pointf dpi; /* device resolution device-units-per-inch */ 335 | 336 | unsigned int width; /* device width - device units */ 337 | unsigned int height; /* device height - device units */ 338 | box pageBoundingBox;/* rotated boundingBox - device units */ 339 | box boundingBox; /* cumulative boundingBox over all pages - device units */ 340 | 341 | pointf scale; /* composite device to graph units (zoom and dpi) */ 342 | pointf translation; /* composite translation */ 343 | pointf devscale; /* composite device to points: dpi, y_goes_down */ 344 | 345 | boolean fit_mode, 346 | needs_refresh, 347 | click, 348 | has_grown, 349 | has_been_rendered; 350 | 351 | unsigned char button; /* active button */ 352 | pointf pointer; /* pointer position in device units */ 353 | pointf oldpointer; /* old pointer position in device units */ 354 | 355 | void *current_obj; /* graph object that pointer is in currently */ 356 | 357 | void *selected_obj; /* graph object that has been selected */ 358 | /* (e.g. button 1 clicked on current obj) */ 359 | char *active_tooltip; /* tooltip of active object - or NULL */ 360 | char *selected_href; /* href of selected object - or NULL */ 361 | gv_argvlist_t selected_obj_type_name; /* (e.g. "edge" "node3" "e" "->" "node5" "") */ 362 | gv_argvlist_t selected_obj_attributes; /* attribute triplets: name, value, type */ 363 | /* e.g. "color", "red", GVATTR_COLOR, 364 | "style", "filled", GVATTR_BOOL, */ 365 | 366 | void *window; /* display-specific data for gvrender plugin */ 367 | 368 | /* keybindings for keyboard events */ 369 | gvevent_key_binding_t *keybindings; 370 | int numkeys; 371 | void *keycodes; 372 | }; 373 | 374 | #ifdef __cplusplus 375 | } 376 | #endif 377 | #endif /* GVCJOB_H */ 378 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvcommon.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVCOMMON_H 15 | #define GVCOMMON_H 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | typedef struct GVCOMMON_s { 22 | char **info; 23 | char *cmdname; 24 | int verbose; 25 | boolean config, auto_outfile_names; 26 | void (*errorfn) (const char *fmt, ...); 27 | const char **show_boxes; /* emit code for correct box coordinates */ 28 | const char **lib; 29 | 30 | /* rendering state */ 31 | int viewNum; /* current view - 1 based count of views, 32 | all pages in all layers */ 33 | const lt_symlist_t *builtins; 34 | int demand_loading; 35 | } GVCOMMON_t; 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | #endif /* GVCOMMON_H */ 41 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvconfig.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | /* Header used by plugins */ 15 | 16 | #ifndef GVCONFIG_H 17 | #define GVCONFIG_H 18 | 19 | #include "gvplugin.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | extern void gvconfig_plugin_install_from_library(GVC_t * gvc, char *path, gvplugin_library_t *library); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | #endif /* GVCONFIG_H */ 31 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvplugin.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | /* Header used by plugins */ 15 | 16 | #ifndef GVPLUGIN_H 17 | #define GVPLUGIN_H 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #include "gvcext.h" 24 | 25 | /* 26 | * Terminology: 27 | * 28 | * package - e.g. libgvplugin_cairo.so 29 | * api - e.g. render 30 | * type - e.g. "png", "ps" 31 | */ 32 | 33 | typedef struct { 34 | int id; /* an id that is only unique within a package 35 | of plugins of the same api. 36 | A renderer-type such as "png" in the cairo package 37 | has an id that is different from the "ps" type 38 | in the same package */ 39 | const char *type; /* a string name, such as "png" or "ps" that 40 | distinguishes different types withing the same 41 | (renderer in this case) */ 42 | int quality; /* an arbitrary integer used for ordering plugins of 43 | the same type from different packages */ 44 | void *engine; /* pointer to the jump table for the plugin */ 45 | void *features; /* pointer to the feature description 46 | void* because type varies by api */ 47 | } gvplugin_installed_t; 48 | 49 | typedef struct { 50 | api_t api; 51 | gvplugin_installed_t *types; 52 | } gvplugin_api_t; 53 | 54 | typedef struct { 55 | char *packagename; /* used when this plugin is builtin and has 56 | no pathname */ 57 | gvplugin_api_t *apis; 58 | } gvplugin_library_t; 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | #endif /* GVPLUGIN_H */ 64 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvplugin_device.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVDEVICE_PLUGIN_H 15 | #define GVDEVICE_PLUGIN_H 16 | 17 | #include "types.h" 18 | #include "gvplugin.h" 19 | #include "gvcjob.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | struct gvdevice_engine_s { 26 | void (*initialize) (GVJ_t * firstjob); 27 | void (*format) (GVJ_t * firstjob); 28 | void (*finalize) (GVJ_t * firstjob); 29 | }; 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | #endif /* GVDEVICE_PLUGIN_H */ 35 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvplugin_layout.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVPLUGIN_LAYOUT_H 15 | #define GVPLUGIN_LAYOUT_H 16 | 17 | #include "types.h" 18 | #include "gvplugin.h" 19 | #include "gvcjob.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | struct gvlayout_engine_s { 26 | void (*layout) (graph_t * g); 27 | void (*cleanup) (graph_t * g); 28 | }; 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif /* GVPLUGIN_LAYOUT_H */ 34 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvplugin_loadimage.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVPLUGIN_IMAGELOAD_H 15 | #define GVPLUGIN_IMAGELOAD_H 16 | 17 | #include "types.h" 18 | #include "gvplugin.h" 19 | #include "gvcjob.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #ifdef GVDLL 26 | # define extern __declspec(dllexport) 27 | #endif 28 | 29 | /*visual studio*/ 30 | #ifdef WIN32 31 | #ifndef GVC_EXPORTS 32 | #define extern __declspec(dllimport) 33 | #endif 34 | #endif 35 | /*end visual studio*/ 36 | 37 | extern boolean gvusershape_file_access(usershape_t *us); 38 | extern void gvusershape_file_release(usershape_t *us); 39 | 40 | struct gvloadimage_engine_s { 41 | void (*loadimage) (GVJ_t *job, usershape_t *us, boxf b, boolean filled); 42 | }; 43 | 44 | #ifdef extern 45 | #undef extern 46 | #endif 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | #endif /* GVPLUGIN_IMAGELOAD_H */ 52 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvplugin_render.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVPLUGIN_RENDER_H 15 | #define GVPLUGIN_RENDER_H 16 | 17 | #include "types.h" 18 | #include "gvplugin.h" 19 | #include "gvcjob.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | struct gvrender_engine_s { 26 | void (*begin_job) (GVJ_t * job); 27 | void (*end_job) (GVJ_t * job); 28 | void (*begin_graph) (GVJ_t * job); 29 | void (*end_graph) (GVJ_t * job); 30 | void (*begin_layer) (GVJ_t * job, char *layername, 31 | int layerNum, int numLayers); 32 | void (*end_layer) (GVJ_t * job); 33 | void (*begin_page) (GVJ_t * job); 34 | void (*end_page) (GVJ_t * job); 35 | void (*begin_cluster) (GVJ_t * job); 36 | void (*end_cluster) (GVJ_t * job); 37 | void (*begin_nodes) (GVJ_t * job); 38 | void (*end_nodes) (GVJ_t * job); 39 | void (*begin_edges) (GVJ_t * job); 40 | void (*end_edges) (GVJ_t * job); 41 | void (*begin_node) (GVJ_t * job); 42 | void (*end_node) (GVJ_t * job); 43 | void (*begin_edge) (GVJ_t * job); 44 | void (*end_edge) (GVJ_t * job); 45 | void (*begin_anchor) (GVJ_t * job, 46 | char *href, char *tooltip, char *target, char *id); 47 | void (*end_anchor) (GVJ_t * job); 48 | void (*begin_label) (GVJ_t * job, label_type type); 49 | void (*end_label) (GVJ_t * job); 50 | void (*textspan) (GVJ_t * job, pointf p, textspan_t * span); 51 | void (*resolve_color) (GVJ_t * job, gvcolor_t * color); 52 | void (*ellipse) (GVJ_t * job, pointf * A, int filled); 53 | void (*polygon) (GVJ_t * job, pointf * A, int n, int filled); 54 | void (*beziercurve) (GVJ_t * job, pointf * A, int n, 55 | int arrow_at_start, int arrow_at_end, int); 56 | void (*polyline) (GVJ_t * job, pointf * A, int n); 57 | void (*comment) (GVJ_t * job, char *comment); 58 | void (*library_shape) (GVJ_t * job, char *name, pointf * A, int n, int filled); 59 | }; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | #endif /* GVPLUGIN_RENDER_H */ 65 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvplugin_textlayout.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GVPLUGIN_TEXTLAYOUT_H 15 | #define GVPLUGIN_TEXTLAYOUT_H 16 | 17 | #include "types.h" 18 | #include "gvplugin.h" 19 | #include "gvcjob.h" 20 | #include "gvcommon.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | struct gvtextlayout_engine_s { 27 | boolean (*textlayout) (textspan_t *span, char** fontpath); 28 | }; 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif /* GVPLUGIN_TEXTLAYOUT_H */ 34 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/gvpr.h: -------------------------------------------------------------------------------- 1 | /* $Id$Revision: */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #ifndef GVPR_H 19 | #define GVPR_H 20 | 21 | #include "cgraph.h" 22 | #ifdef _MSC_VER 23 | typedef int ssize_t; 24 | #endif 25 | 26 | /* Bits for flags variable in gvprstate_t. 27 | * Included here so that calling programs can use the first 28 | * two in gvpropts.flags 29 | */ 30 | /* If set, gvpr calls exit() on errors */ 31 | #define GV_USE_EXIT 1 32 | /* If set, gvpr stores output graphs in gvpropts */ 33 | #define GV_USE_OUTGRAPH 2 34 | /* Use longjmp to return to top-level call in gvpr */ 35 | #define GV_USE_JUMP 4 36 | /* $tvnext has been set but not used */ 37 | #define GV_NEXT_SET 8 38 | 39 | 40 | typedef ssize_t (*gvprwr) (void*, const char *buf, size_t nbyte, void*); 41 | typedef int (*gvpruserfn) (char *); 42 | typedef struct { 43 | char* name; 44 | gvpruserfn fn; 45 | } gvprbinding; 46 | 47 | typedef struct { 48 | Agraph_t** ingraphs; /* NULL-terminated array of input graphs */ 49 | int n_outgraphs; /* if GV_USE_OUTGRAPH set, output graphs */ 50 | Agraph_t** outgraphs; 51 | gvprwr out; /* write function for stdout */ 52 | gvprwr err; /* write function for stderr */ 53 | int flags; 54 | gvprbinding* bindings; /* array of bindings, terminated with {NULL,NULL} */ 55 | } gvpropts; 56 | 57 | extern int gvpr (int argc, char *argv[], gvpropts* opts); 58 | 59 | #endif 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/pack.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | 15 | 16 | #ifndef _PACK_H 17 | #define _PACK_H 1 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #include "types.h" 24 | 25 | /* Type indicating granularity and method 26 | * l_undef - unspecified 27 | * l_node - polyomino using nodes and edges 28 | * l_clust - polyomino using nodes and edges and top-level clusters 29 | * (assumes ND_clust(n) unused by application) 30 | * l_graph - polyomino using computer graph bounding box 31 | * l_array - array based on graph bounding boxes 32 | * l_aspect - tiling based on graph bounding boxes preserving aspect ratio 33 | * l_hull - polyomino using convex hull (unimplemented) 34 | * l_tile - tiling using graph bounding box (unimplemented) 35 | * l_bisect - alternate bisection using graph bounding box (unimplemented) 36 | */ 37 | typedef enum { l_undef, l_clust, l_node, l_graph, l_array, l_aspect } pack_mode; 38 | 39 | #define PK_COL_MAJOR (1 << 0) 40 | #define PK_USER_VALS (1 << 1) 41 | #define PK_LEFT_ALIGN (1 << 2) 42 | #define PK_RIGHT_ALIGN (1 << 3) 43 | #define PK_TOP_ALIGN (1 << 4) 44 | #define PK_BOT_ALIGN (1 << 5) 45 | #define PK_INPUT_ORDER (1 << 6) 46 | 47 | typedef unsigned int packval_t; 48 | 49 | typedef struct { 50 | float aspect; /* desired aspect ratio */ 51 | int sz; /* row/column size size */ 52 | unsigned int margin; /* margin left around objects, in points */ 53 | int doSplines; /* use splines in constructing graph shape */ 54 | pack_mode mode; /* granularity and method */ 55 | boolean *fixed; /* fixed[i] == true implies g[i] should not be moved */ 56 | packval_t* vals; /* for arrays, sort numbers */ 57 | int flags; 58 | } pack_info; 59 | 60 | /*visual studio*/ 61 | #ifdef WIN32 62 | #ifndef GVC_EXPORTS 63 | #define extern __declspec(dllimport) 64 | #endif 65 | #endif 66 | /*end visual studio*/ 67 | 68 | extern point *putRects(int ng, boxf* bbs, pack_info* pinfo); 69 | extern int packRects(int ng, boxf* bbs, pack_info* pinfo); 70 | 71 | extern point *putGraphs(int, Agraph_t **, Agraph_t *, pack_info *); 72 | extern int packGraphs(int, Agraph_t **, Agraph_t *, pack_info *); 73 | extern int packSubgraphs(int, Agraph_t **, Agraph_t *, pack_info *); 74 | extern int pack_graph(int ng, Agraph_t** gs, Agraph_t* root, boolean* fixed); 75 | 76 | extern int shiftGraphs(int, Agraph_t**, point*, Agraph_t*, int); 77 | 78 | extern pack_mode getPackMode(Agraph_t * g, pack_mode dflt); 79 | extern int getPack(Agraph_t *, int not_def, int dflt); 80 | extern pack_mode getPackInfo(Agraph_t * g, pack_mode dflt, int dfltMargin, pack_info*); 81 | extern pack_mode getPackModeInfo(Agraph_t * g, pack_mode dflt, pack_info*); 82 | extern pack_mode parsePackModeInfo(char* p, pack_mode dflt, pack_info* pinfo); 83 | 84 | extern int isConnected(Agraph_t *); 85 | extern Agraph_t **ccomps(Agraph_t *, int *, char *); 86 | extern Agraph_t **cccomps(Agraph_t *, int *, char *); 87 | extern Agraph_t **pccomps(Agraph_t *, int *, char *, boolean *); 88 | extern int nodeInduce(Agraph_t *); 89 | extern Agraph_t *mapClust(Agraph_t *); 90 | #undef extern 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | #endif 95 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/pathgeom.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | 15 | #ifndef _PATHGEOM_INCLUDE 16 | #define _PATHGEOM_INCLUDE 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #ifdef HAVE_POINTF_S 23 | typedef struct pointf_s Ppoint_t; 24 | typedef struct pointf_s Pvector_t; 25 | #else 26 | typedef struct Pxy_t { 27 | double x, y; 28 | } Pxy_t; 29 | 30 | typedef struct Pxy_t Ppoint_t; 31 | typedef struct Pxy_t Pvector_t; 32 | #endif 33 | 34 | typedef struct Ppoly_t { 35 | Ppoint_t *ps; 36 | int pn; 37 | } Ppoly_t; 38 | 39 | typedef Ppoly_t Ppolyline_t; 40 | 41 | typedef struct Pedge_t { 42 | Ppoint_t a, b; 43 | } Pedge_t; 44 | 45 | /* opaque state handle for visibility graph operations */ 46 | typedef struct vconfig_s vconfig_t; 47 | 48 | void freePath(Ppolyline_t* p); 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | #endif 53 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/pathplan.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | 15 | 16 | #ifndef _PATH_INCLUDE 17 | #define _PATH_INCLUDE 18 | 19 | #include "pathgeom.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | 26 | #if defined(_BLD_pathplan) && defined(__EXPORT__) 27 | # define extern __EXPORT__ 28 | #endif 29 | 30 | /* find shortest euclidean path within a simple polygon */ 31 | extern int Pshortestpath(Ppoly_t * boundary, Ppoint_t endpoints[2], 32 | Ppolyline_t * output_route); 33 | 34 | /* fit a spline to an input polyline, without touching barrier segments */ 35 | extern int Proutespline(Pedge_t * barriers, int n_barriers, 36 | Ppolyline_t input_route, 37 | Pvector_t endpoint_slopes[2], 38 | Ppolyline_t * output_route); 39 | 40 | /* utility function to convert from a set of polygonal obstacles to barriers */ 41 | extern int Ppolybarriers(Ppoly_t ** polys, int npolys, 42 | Pedge_t ** barriers, int *n_barriers); 43 | 44 | /* function to convert a polyline into a spline representation */ 45 | extern void make_polyline(Ppolyline_t line, Ppolyline_t* sline); 46 | 47 | #undef extern 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | #endif 53 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/textspan.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef TEXTSPAN_H 15 | #define TEXTSPAN_H 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /* Bold, Italic, Underline, Sup, Sub, Strike */ 22 | /* Stored in textfont_t.flags, which is 7 bits, so full */ 23 | /* Probably should be moved to textspan_t */ 24 | #define HTML_BF (1 << 0) 25 | #define HTML_IF (1 << 1) 26 | #define HTML_UL (1 << 2) 27 | #define HTML_SUP (1 << 3) 28 | #define HTML_SUB (1 << 4) 29 | #define HTML_S (1 << 5) 30 | #define HTML_OL (1 << 6) 31 | 32 | typedef struct _PostscriptAlias { 33 | char* name; 34 | char* family; 35 | char* weight; 36 | char* stretch; 37 | char* style; 38 | int xfig_code; 39 | char* svg_font_family; 40 | char* svg_font_weight; 41 | char* svg_font_style; 42 | } PostscriptAlias; 43 | 44 | /* font information 45 | * If name or color is NULL, or size < 0, that attribute 46 | * is unspecified. 47 | */ 48 | typedef struct { 49 | char* name; 50 | char* color; 51 | PostscriptAlias *postscript_alias; 52 | double size; 53 | unsigned int flags:7; /* HTML_UL, HTML_IF, HTML_BF, etc. */ 54 | unsigned int cnt:(sizeof(unsigned int) * 8 - 7); /* reference count */ 55 | } textfont_t; 56 | 57 | /* atomic unit of text emitted using a single htmlfont_t */ 58 | typedef struct { 59 | char *str; /* stored in utf-8 */ 60 | textfont_t *font; 61 | void *layout; 62 | void (*free_layout) (void *layout); /* FIXME - this is ugly */ 63 | double yoffset_layout, yoffset_centerline; 64 | pointf size; 65 | char just; /* 'l' 'n' 'r' */ /* FIXME */ 66 | } textspan_t; 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | #endif 72 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/types.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef GV_TYPES_H 15 | #define GV_TYPES_H 16 | 17 | /* Define if you want CGRAPH */ 18 | #define WITH_CGRAPH 1 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | typedef unsigned char boolean; 25 | #ifndef NOT 26 | #define NOT(v) (!(v)) 27 | #endif 28 | #ifndef FALSE 29 | #define FALSE 0 30 | #endif 31 | #ifndef TRUE 32 | #define TRUE NOT(FALSE) 33 | #endif 34 | 35 | #include "geom.h" 36 | #include "gvcext.h" 37 | #include "pathgeom.h" 38 | #include "textspan.h" 39 | #include "cgraph.h" 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | typedef int (*qsort_cmpf) (const void *, const void *); 46 | typedef int (*bsearch_cmpf) (const void *, const void *); 47 | typedef struct Agraph_s graph_t; 48 | typedef struct Agnode_s node_t; 49 | typedef struct Agedge_s edge_t; 50 | typedef struct Agsym_s attrsym_t; 51 | #define TAIL_ID "tailport" 52 | #define HEAD_ID "headport" 53 | 54 | typedef struct htmllabel_t htmllabel_t; 55 | 56 | typedef union inside_t { 57 | struct { 58 | pointf* p; 59 | double* r; 60 | } a; 61 | struct { 62 | node_t* n; 63 | boxf* bp; 64 | } s; 65 | } inside_t; 66 | 67 | typedef struct port { /* internal edge endpoint specification */ 68 | pointf p; /* aiming point relative to node center */ 69 | double theta; /* slope in radians */ 70 | boxf *bp; /* if not null, points to bbox of 71 | * rectangular area that is port target 72 | */ 73 | boolean defined; /* if true, edge has port info at this end */ 74 | boolean constrained; /* if true, constraints such as theta are set */ 75 | boolean clip; /* if true, clip end to node/port shape */ 76 | boolean dyna; /* if true, assign compass point dynamically */ 77 | unsigned char order; /* for mincross */ 78 | unsigned char side; /* if port is on perimeter of node, this 79 | * contains the bitwise OR of the sides (TOP, 80 | * BOTTOM, etc.) it is on. 81 | */ 82 | char *name; /* port name, if it was explicitly given, otherwise NULL */ 83 | } port; 84 | 85 | typedef struct { 86 | boolean(*swapEnds) (edge_t * e); /* Should head and tail be swapped? */ 87 | boolean(*splineMerge) (node_t * n); /* Is n a node in the middle of an edge? */ 88 | boolean ignoreSwap; /* Test for swapped edges if false */ 89 | boolean isOrtho; /* Orthogonal routing used */ 90 | } splineInfo; 91 | 92 | typedef struct pathend_t { 93 | boxf nb; /* the node box */ 94 | pointf np; /* node port */ 95 | int sidemask; 96 | int boxn; 97 | boxf boxes[20]; 98 | } pathend_t; 99 | 100 | typedef struct path { /* internal specification for an edge spline */ 101 | port start, end; 102 | int nbox; /* number of subdivisions */ 103 | boxf *boxes; /* rectangular regions of subdivision */ 104 | void *data; 105 | } path; 106 | 107 | typedef struct bezier { 108 | pointf *list; 109 | int size; 110 | int sflag, eflag; 111 | pointf sp, ep; 112 | } bezier; 113 | 114 | typedef struct splines { 115 | bezier *list; 116 | int size; 117 | boxf bb; 118 | } splines; 119 | 120 | typedef struct textlabel_t { 121 | char *text, *fontname, *fontcolor; 122 | int charset; 123 | double fontsize; 124 | pointf dimen; /* the diagonal size of the label (estimated by layout) */ 125 | pointf space; /* the diagonal size of the space for the label */ 126 | /* the rendered label is aligned in this box */ 127 | /* space does not include pad or margin */ 128 | pointf pos; /* the center of the space for the label */ 129 | union { 130 | struct { 131 | textspan_t *span; 132 | short nspans; 133 | } txt; 134 | htmllabel_t *html; 135 | } u; 136 | char valign; /* 't' 'c' 'b' */ 137 | boolean set; /* true if position is set */ 138 | boolean html; /* true if html label */ 139 | } textlabel_t; 140 | 141 | typedef struct polygon_t { /* mutable shape information for a node */ 142 | int regular; /* true for symmetric shapes */ 143 | int peripheries; /* number of periphery lines */ 144 | int sides; /* number of sides */ 145 | double orientation; /* orientation of shape (+ve degrees) */ 146 | double distortion; /* distortion factor - as in trapezium */ 147 | double skew; /* skew factor - as in parallelogram */ 148 | int option; /* ROUNDED, DIAGONAL corners, etc. */ 149 | pointf *vertices; /* array of vertex points */ 150 | } polygon_t; 151 | 152 | typedef struct stroke_t { /* information about a single stroke */ 153 | /* we would have called it a path if that term wasn't already used */ 154 | int nvertices; /* number of points in the stroke */ 155 | int flags; /* stroke style flags */ 156 | pointf *vertices; /* array of vertex points */ 157 | } stroke_t; 158 | 159 | /* flag definitions for stroke_t */ 160 | #define STROKE_CLOSED (1 << 0) 161 | #define STROKE_FILLED (1 << 1) 162 | #define STROKE_PENDOWN (1 << 2) 163 | #define STROKE_VERTICES_ALLOCATED (1 << 3) 164 | 165 | typedef struct shape_t { /* mutable shape information for a node */ 166 | int nstrokes; /* number of strokes in array */ 167 | stroke_t *strokes; /* array of strokes */ 168 | /* The last stroke must always be closed, but can be pen_up. 169 | * It is used as the clipping path */ 170 | } shape_t; 171 | 172 | typedef struct shape_functions { /* read-only shape functions */ 173 | void (*initfn) (node_t *); /* initializes shape from node u.shape_info structure */ 174 | void (*freefn) (node_t *); /* frees shape from node u.shape_info structure */ 175 | port(*portfn) (node_t *, char *, char *); /* finds aiming point and slope of port */ 176 | boolean(*insidefn) (inside_t * inside_context, pointf); /* clips incident gvc->e spline on shape of gvc->n */ 177 | int (*pboxfn)(node_t* n, port* p, int side, boxf rv[], int *kptr); /* finds box path to reach port */ 178 | void (*codefn) (GVJ_t * job, node_t * n); /* emits graphics code for node */ 179 | } shape_functions; 180 | 181 | typedef enum { SH_UNSET, SH_POLY, SH_RECORD, SH_POINT, SH_EPSF} shape_kind; 182 | 183 | typedef struct shape_desc { /* read-only shape descriptor */ 184 | char *name; /* as read from graph file */ 185 | shape_functions *fns; 186 | polygon_t *polygon; /* base polygon info */ 187 | boolean usershape; 188 | } shape_desc; 189 | 190 | #include "usershape.h" /* usershapes needed by gvc */ 191 | 192 | typedef struct nodequeue { 193 | node_t **store, **limit, **head, **tail; 194 | } nodequeue; 195 | 196 | typedef struct adjmatrix_t { 197 | int nrows, ncols; 198 | char *data; 199 | } adjmatrix_t; 200 | 201 | typedef struct rank_t { 202 | int n; /* number of nodes in this rank */ 203 | node_t **v; /* ordered list of nodes in rank */ 204 | int an; /* globally allocated number of nodes */ 205 | node_t **av; /* allocated list of nodes in rank */ 206 | double ht1, ht2; /* height below/above centerline */ 207 | double pht1, pht2; /* as above, but only primitive nodes */ 208 | boolean candidate; /* for transpose () */ 209 | boolean valid; 210 | int cache_nc; /* caches number of crossings */ 211 | adjmatrix_t *flat; 212 | } rank_t; 213 | 214 | typedef enum { R_NONE = 215 | 0, R_VALUE, R_FILL, R_COMPRESS, R_AUTO, R_EXPAND } ratio_t; 216 | 217 | typedef struct layout_t { 218 | double quantum; 219 | double scale; 220 | double ratio; /* set only if ratio_kind == R_VALUE */ 221 | double dpi; 222 | pointf margin; 223 | pointf page; 224 | pointf size; 225 | boolean filled; 226 | boolean landscape; 227 | boolean centered; 228 | ratio_t ratio_kind; 229 | void* xdots; 230 | char* id; 231 | } layout_t; 232 | 233 | /* for "record" shapes */ 234 | typedef struct field_t { 235 | pointf size; /* its dimension */ 236 | boxf b; /* its placement in node's coordinates */ 237 | int n_flds; 238 | textlabel_t *lp; /* n_flds == 0 */ 239 | struct field_t **fld; /* n_flds > 0 */ 240 | char *id; /* user's identifier */ 241 | unsigned char LR; /* if box list is horizontal (left to right) */ 242 | unsigned char sides; /* sides of node exposed to field */ 243 | } field_t; 244 | 245 | typedef struct nlist_t { 246 | node_t **list; 247 | int size; 248 | } nlist_t; 249 | 250 | typedef struct elist { 251 | edge_t **list; 252 | int size; 253 | } elist; 254 | 255 | #define GUI_STATE_ACTIVE (1<<0) 256 | #define GUI_STATE_SELECTED (1<<1) 257 | #define GUI_STATE_VISITED (1<<2) 258 | #define GUI_STATE_DELETED (1<<3) 259 | 260 | #define elist_fastapp(item,L) do {L.list[L.size++] = item; L.list[L.size] = NULL;} while(0) 261 | #define elist_append(item,L) do {L.list = ALLOC(L.size + 2,L.list,edge_t*); L.list[L.size++] = item; L.list[L.size] = NULL;} while(0) 262 | #define alloc_elist(n,L) do {L.size = 0; L.list = N_NEW(n + 1,edge_t*); } while (0) 263 | #define free_list(L) do {if (L.list) free(L.list);} while (0) 264 | 265 | typedef enum {NATIVEFONTS,PSFONTS,SVGFONTS} fontname_kind; 266 | 267 | typedef struct Agraphinfo_t { 268 | Agrec_t hdr; 269 | /* to generate code */ 270 | layout_t *drawing; 271 | textlabel_t *label; /* if the cluster has a title */ 272 | boxf bb; /* bounding box */ 273 | pointf border[4]; /* sizes of margins for graph labels */ 274 | unsigned char gui_state; /* Graph state for GUI ops */ 275 | unsigned char has_labels; 276 | boolean has_images; 277 | unsigned char charset; /* input character set */ 278 | int rankdir; 279 | double ht1, ht2; /* below and above extremal ranks */ 280 | unsigned short flags; 281 | void *alg; 282 | GVC_t *gvc; /* context for "globals" over multiple graphs */ 283 | void (*cleanup) (graph_t * g); /* function to deallocate layout-specific data */ 284 | 285 | #ifndef DOT_ONLY 286 | /* to place nodes */ 287 | node_t **neato_nlist; 288 | int move; 289 | double **dist, **spring, **sum_t, ***t; 290 | unsigned short ndim; 291 | unsigned short odim; 292 | #endif 293 | #ifndef NEATO_ONLY 294 | /* to have subgraphs */ 295 | int n_cluster; 296 | graph_t **clust; /* clusters are in clust[1..n_cluster] !!! */ 297 | graph_t *dotroot; 298 | node_t *nlist; 299 | rank_t *rank; 300 | graph_t *parent; /* containing cluster (not parent subgraph) */ 301 | int level; /* cluster nesting level (not node level!) */ 302 | node_t *minrep, *maxrep; /* set leaders for min and max rank */ 303 | 304 | /* fast graph node list */ 305 | nlist_t comp; 306 | /* connected components */ 307 | node_t *minset, *maxset; /* set leaders */ 308 | long n_nodes; 309 | /* includes virtual */ 310 | short minrank, maxrank; 311 | 312 | /* various flags */ 313 | boolean has_flat_edges; 314 | boolean has_sourcerank; 315 | boolean has_sinkrank; 316 | unsigned char showboxes; 317 | fontname_kind fontnames; /* to override mangling in SVG */ 318 | 319 | int nodesep, ranksep; 320 | node_t *ln, *rn; /* left, right nodes of bounding box */ 321 | 322 | /* for clusters */ 323 | node_t *leader, **rankleader; 324 | boolean expanded; 325 | char installed; 326 | char set_type; 327 | char label_pos; 328 | boolean exact_ranksep; 329 | #endif 330 | 331 | } Agraphinfo_t; 332 | 333 | #define GD_parent(g) (((Agraphinfo_t*)AGDATA(g))->parent) 334 | #define GD_level(g) (((Agraphinfo_t*)AGDATA(g))->level) 335 | #define GD_drawing(g) (((Agraphinfo_t*)AGDATA(g))->drawing) 336 | #define GD_bb(g) (((Agraphinfo_t*)AGDATA(g))->bb) 337 | #define GD_gvc(g) (((Agraphinfo_t*)AGDATA(g))->gvc) 338 | #define GD_cleanup(g) (((Agraphinfo_t*)AGDATA(g))->cleanup) 339 | #define GD_dist(g) (((Agraphinfo_t*)AGDATA(g))->dist) 340 | #define GD_alg(g) (((Agraphinfo_t*)AGDATA(g))->alg) 341 | #define GD_border(g) (((Agraphinfo_t*)AGDATA(g))->border) 342 | #define GD_cl_cnt(g) (((Agraphinfo_t*)AGDATA(g))->cl_nt) 343 | #define GD_clust(g) (((Agraphinfo_t*)AGDATA(g))->clust) 344 | #define GD_dotroot(g) (((Agraphinfo_t*)AGDATA(g))->dotroot) 345 | #define GD_comp(g) (((Agraphinfo_t*)AGDATA(g))->comp) 346 | #define GD_exact_ranksep(g) (((Agraphinfo_t*)AGDATA(g))->exact_ranksep) 347 | #define GD_expanded(g) (((Agraphinfo_t*)AGDATA(g))->expanded) 348 | #define GD_flags(g) (((Agraphinfo_t*)AGDATA(g))->flags) 349 | #define GD_gui_state(g) (((Agraphinfo_t*)AGDATA(g))->gui_state) 350 | #define GD_charset(g) (((Agraphinfo_t*)AGDATA(g))->charset) 351 | #define GD_has_labels(g) (((Agraphinfo_t*)AGDATA(g))->has_labels) 352 | #define GD_has_images(g) (((Agraphinfo_t*)AGDATA(g))->has_images) 353 | #define GD_has_flat_edges(g) (((Agraphinfo_t*)AGDATA(g))->has_flat_edges) 354 | #define GD_has_sourcerank(g) (((Agraphinfo_t*)AGDATA(g))->has_sourcerank) 355 | #define GD_has_sinkrank(g) (((Agraphinfo_t*)AGDATA(g))->has_sinkrank) 356 | #define GD_ht1(g) (((Agraphinfo_t*)AGDATA(g))->ht1) 357 | #define GD_ht2(g) (((Agraphinfo_t*)AGDATA(g))->ht2) 358 | #define GD_inleaf(g) (((Agraphinfo_t*)AGDATA(g))->inleaf) 359 | #define GD_installed(g) (((Agraphinfo_t*)AGDATA(g))->installed) 360 | #define GD_label(g) (((Agraphinfo_t*)AGDATA(g))->label) 361 | #define GD_leader(g) (((Agraphinfo_t*)AGDATA(g))->leader) 362 | #define GD_rankdir2(g) (((Agraphinfo_t*)AGDATA(g))->rankdir) 363 | #define GD_rankdir(g) (((Agraphinfo_t*)AGDATA(g))->rankdir & 0x3) 364 | #define GD_flip(g) (GD_rankdir(g) & 1) 365 | #define GD_realrankdir(g) ((((Agraphinfo_t*)AGDATA(g))->rankdir) >> 2) 366 | #define GD_realflip(g) (GD_realrankdir(g) & 1) 367 | #define GD_ln(g) (((Agraphinfo_t*)AGDATA(g))->ln) 368 | #define GD_maxrank(g) (((Agraphinfo_t*)AGDATA(g))->maxrank) 369 | #define GD_maxset(g) (((Agraphinfo_t*)AGDATA(g))->maxset) 370 | #define GD_minrank(g) (((Agraphinfo_t*)AGDATA(g))->minrank) 371 | #define GD_minset(g) (((Agraphinfo_t*)AGDATA(g))->minset) 372 | #define GD_minrep(g) (((Agraphinfo_t*)AGDATA(g))->minrep) 373 | #define GD_maxrep(g) (((Agraphinfo_t*)AGDATA(g))->maxrep) 374 | #define GD_move(g) (((Agraphinfo_t*)AGDATA(g))->move) 375 | #define GD_n_cluster(g) (((Agraphinfo_t*)AGDATA(g))->n_cluster) 376 | #define GD_n_nodes(g) (((Agraphinfo_t*)AGDATA(g))->n_nodes) 377 | #define GD_ndim(g) (((Agraphinfo_t*)AGDATA(g))->ndim) 378 | #define GD_odim(g) (((Agraphinfo_t*)AGDATA(g))->odim) 379 | #define GD_neato_nlist(g) (((Agraphinfo_t*)AGDATA(g))->neato_nlist) 380 | #define GD_nlist(g) (((Agraphinfo_t*)AGDATA(g))->nlist) 381 | #define GD_nodesep(g) (((Agraphinfo_t*)AGDATA(g))->nodesep) 382 | #define GD_outleaf(g) (((Agraphinfo_t*)AGDATA(g))->outleaf) 383 | #define GD_rank(g) (((Agraphinfo_t*)AGDATA(g))->rank) 384 | #define GD_rankleader(g) (((Agraphinfo_t*)AGDATA(g))->rankleader) 385 | #define GD_ranksep(g) (((Agraphinfo_t*)AGDATA(g))->ranksep) 386 | #define GD_rn(g) (((Agraphinfo_t*)AGDATA(g))->rn) 387 | #define GD_set_type(g) (((Agraphinfo_t*)AGDATA(g))->set_type) 388 | #define GD_label_pos(g) (((Agraphinfo_t*)AGDATA(g))->label_pos) 389 | #define GD_showboxes(g) (((Agraphinfo_t*)AGDATA(g))->showboxes) 390 | #define GD_fontnames(g) (((Agraphinfo_t*)AGDATA(g))->fontnames) 391 | #define GD_spring(g) (((Agraphinfo_t*)AGDATA(g))->spring) 392 | #define GD_sum_t(g) (((Agraphinfo_t*)AGDATA(g))->sum_t) 393 | #define GD_t(g) (((Agraphinfo_t*)AGDATA(g))->t) 394 | 395 | typedef struct Agnodeinfo_t { 396 | Agrec_t hdr; 397 | shape_desc *shape; 398 | void *shape_info; 399 | pointf coord; 400 | double width, height; /* inches */ 401 | boxf bb; 402 | double ht, lw, rw; 403 | textlabel_t *label; 404 | textlabel_t *xlabel; 405 | void *alg; 406 | char state; 407 | unsigned char gui_state; /* Node state for GUI ops */ 408 | boolean clustnode; 409 | 410 | #ifndef DOT_ONLY 411 | unsigned char pinned; 412 | int id, heapindex, hops; 413 | double *pos, dist; 414 | #endif 415 | #ifndef NEATO_ONLY 416 | unsigned char showboxes; 417 | boolean has_port; 418 | node_t* rep; 419 | node_t *set; 420 | 421 | /* fast graph */ 422 | char node_type, mark, onstack; 423 | char ranktype, weight_class; 424 | node_t *next, *prev; 425 | elist in, out, flat_out, flat_in, other; 426 | graph_t *clust; 427 | 428 | /* for union-find and collapsing nodes */ 429 | int UF_size; 430 | node_t *UF_parent; 431 | node_t *inleaf, *outleaf; 432 | 433 | /* for placing nodes */ 434 | int rank, order; /* initially, order = 1 for ordered edges */ 435 | double mval; 436 | elist save_in, save_out; 437 | 438 | /* for network-simplex */ 439 | elist tree_in, tree_out; 440 | edge_t *par; 441 | int low, lim; 442 | int priority; 443 | 444 | double pad[1]; 445 | #endif 446 | 447 | } Agnodeinfo_t; 448 | 449 | #define ND_id(n) (((Agnodeinfo_t*)AGDATA(n))->id) 450 | #define ND_alg(n) (((Agnodeinfo_t*)AGDATA(n))->alg) 451 | #define ND_UF_parent(n) (((Agnodeinfo_t*)AGDATA(n))->UF_parent) 452 | #define ND_set(n) (((Agnodeinfo_t*)AGDATA(n))->set) 453 | #define ND_UF_size(n) (((Agnodeinfo_t*)AGDATA(n))->UF_size) 454 | #define ND_bb(n) (((Agnodeinfo_t*)AGDATA(n))->bb) 455 | #define ND_clust(n) (((Agnodeinfo_t*)AGDATA(n))->clust) 456 | #define ND_coord(n) (((Agnodeinfo_t*)AGDATA(n))->coord) 457 | #define ND_dist(n) (((Agnodeinfo_t*)AGDATA(n))->dist) 458 | #define ND_flat_in(n) (((Agnodeinfo_t*)AGDATA(n))->flat_in) 459 | #define ND_flat_out(n) (((Agnodeinfo_t*)AGDATA(n))->flat_out) 460 | #define ND_gui_state(n) (((Agnodeinfo_t*)AGDATA(n))->gui_state) 461 | #define ND_has_port(n) (((Agnodeinfo_t*)AGDATA(n))->has_port) 462 | #define ND_rep(n) (((Agnodeinfo_t*)AGDATA(n))->rep) 463 | #define ND_heapindex(n) (((Agnodeinfo_t*)AGDATA(n))->heapindex) 464 | #define ND_height(n) (((Agnodeinfo_t*)AGDATA(n))->height) 465 | #define ND_hops(n) (((Agnodeinfo_t*)AGDATA(n))->hops) 466 | #define ND_ht(n) (((Agnodeinfo_t*)AGDATA(n))->ht) 467 | #define ND_in(n) (((Agnodeinfo_t*)AGDATA(n))->in) 468 | #define ND_inleaf(n) (((Agnodeinfo_t*)AGDATA(n))->inleaf) 469 | #define ND_label(n) (((Agnodeinfo_t*)AGDATA(n))->label) 470 | #define ND_xlabel(n) (((Agnodeinfo_t*)AGDATA(n))->xlabel) 471 | #define ND_lim(n) (((Agnodeinfo_t*)AGDATA(n))->lim) 472 | #define ND_low(n) (((Agnodeinfo_t*)AGDATA(n))->low) 473 | #define ND_lw(n) (((Agnodeinfo_t*)AGDATA(n))->lw) 474 | #define ND_mark(n) (((Agnodeinfo_t*)AGDATA(n))->mark) 475 | #define ND_mval(n) (((Agnodeinfo_t*)AGDATA(n))->mval) 476 | #define ND_n_cluster(n) (((Agnodeinfo_t*)AGDATA(n))->n_cluster) 477 | #define ND_next(n) (((Agnodeinfo_t*)AGDATA(n))->next) 478 | #define ND_node_type(n) (((Agnodeinfo_t*)AGDATA(n))->node_type) 479 | #define ND_onstack(n) (((Agnodeinfo_t*)AGDATA(n))->onstack) 480 | #define ND_order(n) (((Agnodeinfo_t*)AGDATA(n))->order) 481 | #define ND_other(n) (((Agnodeinfo_t*)AGDATA(n))->other) 482 | #define ND_out(n) (((Agnodeinfo_t*)AGDATA(n))->out) 483 | #define ND_outleaf(n) (((Agnodeinfo_t*)AGDATA(n))->outleaf) 484 | #define ND_par(n) (((Agnodeinfo_t*)AGDATA(n))->par) 485 | #define ND_pinned(n) (((Agnodeinfo_t*)AGDATA(n))->pinned) 486 | #define ND_pos(n) (((Agnodeinfo_t*)AGDATA(n))->pos) 487 | #define ND_prev(n) (((Agnodeinfo_t*)AGDATA(n))->prev) 488 | #define ND_priority(n) (((Agnodeinfo_t*)AGDATA(n))->priority) 489 | #define ND_rank(n) (((Agnodeinfo_t*)AGDATA(n))->rank) 490 | #define ND_ranktype(n) (((Agnodeinfo_t*)AGDATA(n))->ranktype) 491 | #define ND_rw(n) (((Agnodeinfo_t*)AGDATA(n))->rw) 492 | #define ND_save_in(n) (((Agnodeinfo_t*)AGDATA(n))->save_in) 493 | #define ND_save_out(n) (((Agnodeinfo_t*)AGDATA(n))->save_out) 494 | #define ND_shape(n) (((Agnodeinfo_t*)AGDATA(n))->shape) 495 | #define ND_shape_info(n) (((Agnodeinfo_t*)AGDATA(n))->shape_info) 496 | #define ND_showboxes(n) (((Agnodeinfo_t*)AGDATA(n))->showboxes) 497 | #define ND_state(n) (((Agnodeinfo_t*)AGDATA(n))->state) 498 | #define ND_clustnode(n) (((Agnodeinfo_t*)AGDATA(n))->clustnode) 499 | #define ND_tree_in(n) (((Agnodeinfo_t*)AGDATA(n))->tree_in) 500 | #define ND_tree_out(n) (((Agnodeinfo_t*)AGDATA(n))->tree_out) 501 | #define ND_weight_class(n) (((Agnodeinfo_t*)AGDATA(n))->weight_class) 502 | #define ND_width(n) (((Agnodeinfo_t*)AGDATA(n))->width) 503 | #define ND_xsize(n) (ND_lw(n)+ND_rw(n)) 504 | #define ND_ysize(n) (ND_ht(n)) 505 | 506 | typedef struct Agedgeinfo_t { 507 | Agrec_t hdr; 508 | splines *spl; 509 | port tail_port, head_port; 510 | textlabel_t *label, *head_label, *tail_label, *xlabel; 511 | char edge_type; 512 | char adjacent; /* true for flat edge with adjacent nodes */ 513 | char label_ontop; 514 | unsigned char gui_state; /* Edge state for GUI ops */ 515 | edge_t *to_orig; /* for dot's shapes.c */ 516 | void *alg; 517 | 518 | #ifndef DOT_ONLY 519 | double factor; 520 | double dist; 521 | Ppolyline_t path; 522 | #endif 523 | #ifndef NEATO_ONLY 524 | unsigned char showboxes; 525 | boolean conc_opp_flag; 526 | short xpenalty; 527 | int weight; 528 | int cutvalue, tree_index; 529 | short count; 530 | unsigned short minlen; 531 | edge_t *to_virt; 532 | #endif 533 | } Agedgeinfo_t; 534 | 535 | #define ED_alg(e) (((Agedgeinfo_t*)AGDATA(e))->alg) 536 | #define ED_conc_opp_flag(e) (((Agedgeinfo_t*)AGDATA(e))->conc_opp_flag) 537 | #define ED_count(e) (((Agedgeinfo_t*)AGDATA(e))->count) 538 | #define ED_cutvalue(e) (((Agedgeinfo_t*)AGDATA(e))->cutvalue) 539 | #define ED_edge_type(e) (((Agedgeinfo_t*)AGDATA(e))->edge_type) 540 | #define ED_adjacent(e) (((Agedgeinfo_t*)AGDATA(e))->adjacent) 541 | #define ED_factor(e) (((Agedgeinfo_t*)AGDATA(e))->factor) 542 | #define ED_gui_state(e) (((Agedgeinfo_t*)AGDATA(e))->gui_state) 543 | #define ED_head_label(e) (((Agedgeinfo_t*)AGDATA(e))->head_label) 544 | #define ED_head_port(e) (((Agedgeinfo_t*)AGDATA(e))->head_port) 545 | #define ED_label(e) (((Agedgeinfo_t*)AGDATA(e))->label) 546 | #define ED_xlabel(e) (((Agedgeinfo_t*)AGDATA(e))->xlabel) 547 | #define ED_label_ontop(e) (((Agedgeinfo_t*)AGDATA(e))->label_ontop) 548 | #define ED_minlen(e) (((Agedgeinfo_t*)AGDATA(e))->minlen) 549 | #define ED_path(e) (((Agedgeinfo_t*)AGDATA(e))->path) 550 | #define ED_showboxes(e) (((Agedgeinfo_t*)AGDATA(e))->showboxes) 551 | #define ED_spl(e) (((Agedgeinfo_t*)AGDATA(e))->spl) 552 | #define ED_tail_label(e) (((Agedgeinfo_t*)AGDATA(e))->tail_label) 553 | #define ED_tail_port(e) (((Agedgeinfo_t*)AGDATA(e))->tail_port) 554 | #define ED_to_orig(e) (((Agedgeinfo_t*)AGDATA(e))->to_orig) 555 | #define ED_to_virt(e) (((Agedgeinfo_t*)AGDATA(e))->to_virt) 556 | #define ED_tree_index(e) (((Agedgeinfo_t*)AGDATA(e))->tree_index) 557 | #define ED_xpenalty(e) (((Agedgeinfo_t*)AGDATA(e))->xpenalty) 558 | #define ED_dist(e) (((Agedgeinfo_t*)AGDATA(e))->dist) 559 | #define ED_weight(e) (((Agedgeinfo_t*)AGDATA(e))->weight) 560 | 561 | #define ag_xget(x,a) agxget(x,a) 562 | #define SET_RANKDIR(g,rd) (GD_rankdir2(g) = rd) 563 | #define agfindedge(g,t,h) (agedge(g,t,h,NULL,0)) 564 | #define agfindnode(g,n) (agnode(g,n,0)) 565 | #define agfindgraphattr(g,a) (agattr(g,AGRAPH,a,NULL)) 566 | #define agfindnodeattr(g,a) (agattr(g,AGNODE,a,NULL)) 567 | #define agfindedgeattr(g,a) (agattr(g,AGEDGE,a,NULL)) 568 | 569 | typedef struct { 570 | int flags; 571 | } gvlayout_features_t; 572 | 573 | #ifdef __cplusplus 574 | } 575 | #endif 576 | #endif 577 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/usershape.h: -------------------------------------------------------------------------------- 1 | /* $Id$ $Revision$ */ 2 | /* vim:set shiftwidth=4 ts=8: */ 3 | 4 | /************************************************************************* 5 | * Copyright (c) 2011 AT&T Intellectual Property 6 | * All rights reserved. This program and the accompanying materials 7 | * are made available under the terms of the Eclipse Public License v1.0 8 | * which accompanies this distribution, and is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 12 | *************************************************************************/ 13 | 14 | #ifndef USERSHAPE_H 15 | #define USERSHAPE_H 16 | 17 | #include "cdt.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | typedef enum { FT_NULL, 24 | FT_BMP, FT_GIF, FT_PNG, FT_JPEG, 25 | FT_PDF, FT_PS, FT_EPS, FT_SVG, FT_XML, 26 | FT_RIFF, FT_WEBP, FT_ICO, FT_TIFF 27 | } imagetype_t; 28 | 29 | typedef enum { 30 | IMAGESCALE_FALSE, /* no image scaling */ 31 | IMAGESCALE_TRUE, /* scale image to fit but keep aspect ratio */ 32 | IMAGESCALE_WIDTH, /* scale image width to fit, keep height fixed */ 33 | IMAGESCALE_HEIGHT, /* scale image height to fit, keep width fixed */ 34 | IMAGESCALE_BOTH /* scale image to fit without regard for aspect ratio */ 35 | } imagescale_t; 36 | 37 | typedef struct usershape_s usershape_t; 38 | 39 | struct usershape_s { 40 | Dtlink_t link; 41 | const char *name; 42 | int macro_id; 43 | boolean must_inline; 44 | boolean nocache; 45 | FILE *f; 46 | imagetype_t type; 47 | char *stringtype; 48 | int x, y, w, h, dpi; 49 | void *data; /* data loaded by a renderer */ 50 | size_t datasize; /* size of data (if mmap'ed) */ 51 | void (*datafree)(usershape_t *us); /* renderer's function for freeing data */ 52 | }; 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | #endif 58 | -------------------------------------------------------------------------------- /GraphLayout/Classes/graphviz/xdot.h: -------------------------------------------------------------------------------- 1 | /* vim:set shiftwidth=4 ts=8: */ 2 | 3 | /************************************************************************* 4 | * Copyright (c) 2011 AT&T Intellectual Property 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ 11 | *************************************************************************/ 12 | 13 | #ifndef XDOT_H 14 | #define XDOT_H 15 | #include 16 | #ifdef WIN32 17 | #include 18 | #endif 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define INITIAL_XDOT_CAPACITY 512 25 | 26 | typedef enum { 27 | xd_none, 28 | xd_linear, 29 | xd_radial 30 | } xdot_grad_type; 31 | 32 | typedef struct { 33 | float frac; 34 | char* color; 35 | } xdot_color_stop; 36 | 37 | typedef struct { 38 | double x0, y0; 39 | double x1, y1; 40 | int n_stops; 41 | xdot_color_stop* stops; 42 | } xdot_linear_grad; 43 | 44 | typedef struct { 45 | double x0, y0, r0; 46 | double x1, y1, r1; 47 | int n_stops; 48 | xdot_color_stop* stops; 49 | } xdot_radial_grad; 50 | 51 | typedef struct { 52 | xdot_grad_type type; 53 | union { 54 | char* clr; 55 | xdot_linear_grad ling; 56 | xdot_radial_grad ring; 57 | } u; 58 | } xdot_color; 59 | 60 | typedef enum { 61 | xd_left, xd_center, xd_right 62 | } xdot_align; 63 | 64 | typedef struct { 65 | double x, y, z; 66 | } xdot_point; 67 | 68 | typedef struct { 69 | double x, y, w, h; 70 | } xdot_rect; 71 | 72 | typedef struct { 73 | int cnt; 74 | xdot_point* pts; 75 | } xdot_polyline; 76 | 77 | typedef struct { 78 | double x, y; 79 | xdot_align align; 80 | double width; 81 | char* text; 82 | } xdot_text; 83 | 84 | typedef struct { 85 | xdot_rect pos; 86 | char* name; 87 | } xdot_image; 88 | 89 | typedef struct { 90 | double size; 91 | char* name; 92 | } xdot_font; 93 | 94 | typedef enum { 95 | xd_filled_ellipse, xd_unfilled_ellipse, 96 | xd_filled_polygon, xd_unfilled_polygon, 97 | xd_filled_bezier, xd_unfilled_bezier, 98 | xd_polyline, xd_text, 99 | xd_fill_color, xd_pen_color, xd_font, xd_style, xd_image, 100 | xd_grad_fill_color, xd_grad_pen_color, 101 | xd_fontchar 102 | } xdot_kind; 103 | 104 | typedef enum { 105 | xop_ellipse, 106 | xop_polygon, 107 | xop_bezier, 108 | xop_polyline, xop_text, 109 | xop_fill_color, xop_pen_color, xop_font, xop_style, xop_image, 110 | xop_grad_color, 111 | xop_fontchar 112 | } xop_kind; 113 | 114 | typedef struct _xdot_op xdot_op; 115 | typedef void (*drawfunc_t)(xdot_op*, int); 116 | typedef void (*freefunc_t)(xdot_op*); 117 | 118 | struct _xdot_op { 119 | xdot_kind kind; 120 | union { 121 | xdot_rect ellipse; /* xd_filled_ellipse, xd_unfilled_ellipse */ 122 | xdot_polyline polygon; /* xd_filled_polygon, xd_unfilled_polygon */ 123 | xdot_polyline polyline; /* xd_polyline */ 124 | xdot_polyline bezier; /* xd_filled_bezier, xd_unfilled_bezier */ 125 | xdot_text text; /* xd_text */ 126 | xdot_image image; /* xd_image */ 127 | char* color; /* xd_fill_color, xd_pen_color */ 128 | xdot_color grad_color; /* xd_grad_fill_color, xd_grad_pen_color */ 129 | xdot_font font; /* xd_font */ 130 | char* style; /* xd_style */ 131 | unsigned int fontchar; /* xd_fontchar */ 132 | } u; 133 | drawfunc_t drawfunc; 134 | }; 135 | 136 | #define XDOT_PARSE_ERROR 1 137 | 138 | typedef struct { 139 | int cnt; /* no. of xdot ops */ 140 | int sz; /* sizeof structure containing xdot_op as first field */ 141 | xdot_op* ops; 142 | freefunc_t freefunc; 143 | int flags; 144 | } xdot; 145 | 146 | typedef struct { 147 | int cnt; /* no. of xdot ops */ 148 | int n_ellipse; 149 | int n_polygon; 150 | int n_polygon_pts; 151 | int n_polyline; 152 | int n_polyline_pts; 153 | int n_bezier; 154 | int n_bezier_pts; 155 | int n_text; 156 | int n_font; 157 | int n_style; 158 | int n_color; 159 | int n_image; 160 | int n_gradcolor; 161 | int n_fontchar; 162 | } xdot_stats; 163 | 164 | /* ops are indexed by xop_kind */ 165 | extern xdot* parseXDotF (char*, drawfunc_t opfns[], int sz); 166 | extern xdot* parseXDotFOn (char*, drawfunc_t opfns[], int sz, xdot*); 167 | extern xdot* parseXDot (char*); 168 | extern char* sprintXDot (xdot*); 169 | extern void fprintXDot (FILE*, xdot*); 170 | extern void jsonXDot (FILE*, xdot*); 171 | extern void freeXDot (xdot*); 172 | extern int statXDot (xdot*, xdot_stats*); 173 | extern xdot_grad_type colorTypeXDot (char*); 174 | extern char* parseXDotColor (char* cp, xdot_color* clr); 175 | extern void freeXDotColor (xdot_color*); 176 | 177 | #ifdef __cplusplus 178 | } 179 | #endif 180 | #endif 181 | -------------------------------------------------------------------------------- /GraphLayout/Classes/objc/GVLGraph.h: -------------------------------------------------------------------------------- 1 | // 2 | // GVLGraph.h 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. 6 | // MIT License 7 | // 8 | 9 | #import "gvc.h" 10 | #import 11 | #import 12 | #import 13 | 14 | @interface GVLNode : NSObject 15 | @property Agraph_t *parent; 16 | @property Agnode_t *node; 17 | @property NSString *label; 18 | - (void)setAttribute:(NSString *)value forKey:(NSString *)key; 19 | - (NSString *)getAttributeForKey:(NSString *)key; 20 | - (void)prepare; 21 | - (UIBezierPath *)path; 22 | - (CGPoint)origin; 23 | - (CGRect)frame; 24 | - (CGRect)bounds; 25 | @end 26 | 27 | @interface GVLEdge : NSObject 28 | @property Agraph_t *parent; 29 | @property Agedge_t *edge; 30 | - (void)setAttribute:(NSString *)value forKey:(NSString *)key; 31 | - (NSString *)getAttributeForKey:(NSString *)key; 32 | - (void)prepare; 33 | - (CGRect)frame; 34 | - (CGRect)bounds; 35 | - (UIBezierPath *)path; 36 | - (UIBezierPath *)body; 37 | - (UIBezierPath *)headArrow; 38 | - (UIBezierPath *)tailArrow; 39 | @end 40 | 41 | @interface GVLGraph : NSObject 42 | 43 | @property NSMutableArray *nodes; 44 | @property NSMutableArray *edges; 45 | 46 | - (NSString *)getAttributeForKey:(NSString *)key; 47 | 48 | - (void)setAttribute:(NSString *)value forKey:(NSString *)key; 49 | 50 | - (GVLNode *)addNode:(NSString *)label; 51 | - (GVLEdge *)addEdgeWithSource:(GVLNode *)source andTarget:(GVLNode *)target; 52 | //-(id)addSubGraph; 53 | 54 | - (BOOL)deleteNode:(GVLNode *)node; 55 | - (BOOL)deleteEdge:(GVLEdge *)edge; 56 | - (BOOL)loadLayout:(NSString *)text; 57 | - (BOOL)applyLayout; 58 | - (CGSize)size; 59 | 60 | @end 61 | 62 | @interface GVLUtils : NSObject 63 | + (float)getHeightForGraph:(Agraph_t *)graph; 64 | + (NSMutableArray *)toPolygon:(const polygon_t *)poly 65 | width:(float)width 66 | height:(float)height; 67 | + (CGPathRef)toPathWithType:(const char *)type 68 | poly:(const polygon_t *)poly 69 | width:(float)width 70 | height:(float)height; 71 | + (CGPathRef)toPathWithSplines:(const splines *)spl height:(float)height; 72 | + (CGPathRef)toPath:(NSArray *)points; 73 | + (CGPoint)toPointF:(pointf)p height:(float)height; 74 | + (CGPoint)toPoint:(point)p height:(float)height; 75 | + (CGPoint)centerToOrigin:(CGPoint)point 76 | width:(float)width 77 | height:(float)height; 78 | // +(?)toBrushStyle:(NSString*) style; 79 | // +(?)toPenStyle:(NSString*)style; 80 | + (CGColorRef)toColor:(NSString *)name; 81 | + (UIBezierPath *)arrowFrom:(CGPoint)start 82 | to:(CGPoint)end 83 | tailWidth:(CGFloat)tailWidth 84 | headWidth:(CGFloat)headWidth 85 | headLength:(CGFloat)headLength; 86 | @end 87 | 88 | @interface GVLConfig : NSObject 89 | + (float)dpi; 90 | + (void)setDpi:(float)value; 91 | @end 92 | -------------------------------------------------------------------------------- /GraphLayout/Classes/objc/GVLGraph.mm: -------------------------------------------------------------------------------- 1 | // 2 | // GVLGraph.m 3 | // GraphLayout 4 | // 5 | // Copyright © 2018 bakhtiyor.com. 6 | // MIT License 7 | // 8 | 9 | #import "GVLGraph.h" 10 | 11 | extern gvplugin_library_t gvplugin_dot_layout_LTX_library; 12 | // extern gvplugin_library_t gvplugin_neato_layout_LTX_library; 13 | extern gvplugin_library_t gvplugin_core_LTX_library; 14 | // extern gvplugin_library_t gvplugin_quartz_LTX_library; 15 | // extern gvplugin_library_t gvplugin_visio_LTX_library; 16 | 17 | char empty[] = ""; 18 | float _dpi = 72.0f; 19 | 20 | #define kArrowPointCount 7 21 | 22 | @implementation GVLNode { 23 | UIBezierPath *_bezierPath; 24 | CGRect _frame; 25 | CGRect _bounds; 26 | CGPoint _origin; 27 | } 28 | 29 | @synthesize label = _label; 30 | 31 | - (void)setAttribute:(NSString *)value forKey:(NSString *)key { 32 | agsafeset(self.node, (char *)[key UTF8String], (char *)[value UTF8String], 33 | empty); 34 | } 35 | 36 | - (NSString *)getAttributeForKey:(NSString *)key { 37 | char *raw = agget(self.node, (char *)[key UTF8String]); 38 | if (raw) { 39 | return [NSString stringWithUTF8String:raw]; 40 | } 41 | return @""; 42 | } 43 | 44 | - (NSString *)label { 45 | return _label; 46 | } 47 | 48 | - (void)setLabel:(NSString *)label { 49 | _label = label; 50 | [self setAttribute:label forKey:@"label"]; 51 | } 52 | 53 | - (void)prepare { 54 | float width = ND_width(self.node) * _dpi; 55 | float height = ND_height(self.node) * _dpi; 56 | CGPathRef cgpath = 57 | [GVLUtils toPathWithType:ND_shape(self.node)->name 58 | poly:(polygon_t *)ND_shape_info(self.node) 59 | width:width 60 | height:height]; 61 | if (cgpath) { 62 | _bezierPath = [UIBezierPath bezierPathWithCGPath:cgpath]; 63 | } 64 | float gheight = [GVLUtils getHeightForGraph:self.parent]; 65 | CGPoint point = [GVLUtils toPointF:ND_coord(self.node) height:gheight]; 66 | _origin = [GVLUtils centerToOrigin:point width:width height:height]; 67 | _bounds = CGRectMake(0, 0, width, height); 68 | _frame = CGRectMake(_origin.x, _origin.y, width, height); 69 | } 70 | 71 | - (UIBezierPath *)path { 72 | return _bezierPath; 73 | } 74 | 75 | - (CGPoint)origin { 76 | return _origin; 77 | } 78 | 79 | - (CGRect)frame { 80 | return _frame; 81 | } 82 | 83 | - (CGRect)bounds { 84 | return _bounds; 85 | } 86 | 87 | @end 88 | 89 | @implementation GVLEdge { 90 | CGRect _bounds; 91 | CGRect _frame; 92 | UIBezierPath *_bezierPath; 93 | UIBezierPath *_body; 94 | UIBezierPath *_head; 95 | UIBezierPath *_tail; 96 | } 97 | - (void)setAttribute:(NSString *)value forKey:(NSString *)key { 98 | agsafeset(self.edge, (char *)[key UTF8String], (char *)[value UTF8String], 99 | empty); 100 | } 101 | 102 | - (NSString *)getAttributeForKey:(NSString *)key { 103 | char *raw = agget(self.edge, (char *)[key UTF8String]); 104 | if (raw) { 105 | return [NSString stringWithUTF8String:raw]; 106 | } 107 | return @""; 108 | } 109 | 110 | - (void)prepare { 111 | float gheight = [GVLUtils getHeightForGraph:self.parent]; 112 | const splines *bodySpl = ED_spl(self.edge); 113 | CGPathRef bodyPath = [GVLUtils toPathWithSplines:bodySpl height:gheight]; 114 | if (bodyPath) { 115 | _body = [UIBezierPath bezierPathWithCGPath:bodyPath]; 116 | _bezierPath = [UIBezierPath bezierPathWithCGPath:bodyPath]; 117 | } 118 | 119 | _head = [self toArrow:ED_spl(self.edge) withHeight:gheight]; 120 | _tail = [self toArrow:ED_spl(self.edge) withHeight:gheight]; 121 | 122 | if (_bezierPath) { 123 | if (_head) { 124 | [_bezierPath appendPath:_head]; 125 | } 126 | if (_tail) { 127 | [_bezierPath appendPath:_tail]; 128 | } 129 | } 130 | _frame = [_body bounds]; 131 | if (_head) { 132 | _frame = CGRectUnion(_frame, [_head bounds]); 133 | } 134 | if (_tail) { 135 | _frame = CGRectUnion(_frame, [_tail bounds]); 136 | } 137 | _bounds = CGRectMake(0, 0, _frame.size.width, _frame.size.height); 138 | 139 | // normalize bezier paths 140 | CGAffineTransform move = 141 | CGAffineTransformMakeTranslation(-_frame.origin.x, -_frame.origin.y); 142 | [_body applyTransform:move]; 143 | [_head applyTransform:move]; 144 | [_tail applyTransform:move]; 145 | } 146 | 147 | - (CGRect)frame { 148 | return _frame; 149 | } 150 | 151 | - (CGRect)bounds { 152 | return _bounds; 153 | } 154 | 155 | - (UIBezierPath *)path { 156 | return _bezierPath; 157 | } 158 | 159 | - (UIBezierPath *)body { 160 | return _body; 161 | } 162 | 163 | - (UIBezierPath *)headArrow { 164 | return _head; 165 | } 166 | 167 | - (UIBezierPath *)tailArrow { 168 | return _tail; 169 | } 170 | 171 | - (UIBezierPath *)toArrow:(const splines *)spl withHeight:(float)gheight { 172 | if ((spl->list != 0) && (spl->list->size % 3 == 1)) { 173 | if (spl->list->eflag) { 174 | CGPoint p1 = [GVLUtils toPointF:spl->list->list[spl->list->size - 1] 175 | height:gheight]; 176 | CGPoint p2 = [GVLUtils toPointF:spl->list->ep height:gheight]; 177 | return [GVLUtils arrowFrom:p1 178 | to:p2 179 | tailWidth:0.5 180 | headWidth:8 181 | headLength:12]; 182 | } 183 | } 184 | return NULL; 185 | } 186 | 187 | @end 188 | 189 | @implementation GVLGraph { 190 | Agraph_t *_graph; 191 | GVC_t *_context; 192 | } 193 | 194 | - (instancetype)init { 195 | self = [super init]; 196 | if (self) { 197 | NSString *name = [NSString stringWithFormat:@"graph_%d", arc4random()]; 198 | 199 | _context = gvContext(); 200 | gvAddLibrary(_context, &gvplugin_dot_layout_LTX_library); 201 | // gvAddLibrary(_context, &gvplugin_neato_layout_LTX_library); 202 | gvAddLibrary(_context, &gvplugin_core_LTX_library); 203 | _graph = agopen((char *)[name UTF8String], Agdirected, NULL); 204 | 205 | self.nodes = [NSMutableArray array]; 206 | self.edges = [NSMutableArray array]; 207 | 208 | // Set graph attributes 209 | [self setAttribute:@"spline" forKey:@"splines"]; 210 | [self setAttribute:@"scalexy" forKey:@"overlap"]; 211 | } 212 | return self; 213 | } 214 | 215 | - (NSString *)getAttributeForKey:(NSString *)key { 216 | char *value = agget(_graph, (char *)[key UTF8String]); 217 | if (value) { 218 | return [NSString stringWithUTF8String:value]; 219 | } 220 | return NULL; 221 | } 222 | 223 | - (void)setAttribute:(NSString *)value forKey:(NSString *)key { 224 | agsafeset(_graph, (char *)[key UTF8String], (char *)[value UTF8String], 225 | empty); 226 | } 227 | 228 | - (GVLNode *)addNode:(NSString *)label { 229 | GVLNode *node = [[GVLNode alloc] init]; 230 | node.node = agnode(_graph, NULL, TRUE); 231 | if (!node.node) { 232 | NSLog(@"Error adding node %@", label); 233 | } 234 | node.parent = _graph; 235 | node.label = label; 236 | [self.nodes addObject:node]; 237 | return node; 238 | } 239 | 240 | - (GVLEdge *)addEdgeWithSource:(GVLNode *)source andTarget:(GVLNode *)target { 241 | GVLEdge *edge = [[GVLEdge alloc] init]; 242 | edge.edge = agedge(_graph, source.node, target.node, NULL, TRUE); 243 | if (!edge.edge) { 244 | NSLog(@"Error adding edge %@ - %@", source.label, target.label); 245 | } 246 | edge.parent = _graph; 247 | [self.edges addObject:edge]; 248 | return edge; 249 | } 250 | 251 | - (BOOL)deleteNode:(GVLNode *)node { 252 | if ([self.nodes containsObject:node]) { 253 | agdelnode(_graph, node.node); 254 | [self.nodes removeObject:node]; 255 | return YES; 256 | } 257 | return NO; 258 | } 259 | 260 | - (BOOL)deleteEdge:(GVLEdge *)edge { 261 | if ([self.edges containsObject:edge]) { 262 | agdeledge(_graph, edge.edge); 263 | [self.edges removeObject:edge]; 264 | return YES; 265 | } 266 | return NO; 267 | } 268 | 269 | - (BOOL)loadLayout:(NSString *)text { 270 | const char *cp = [text cStringUsingEncoding:NSUTF8StringEncoding]; 271 | Agraph_t *graph = agmemread(cp); 272 | if (gvLayout(_context, graph, (char *)"dot") != 0) { 273 | return NO; 274 | } 275 | [_nodes removeAllObjects]; 276 | [_edges removeAllObjects]; 277 | _graph = graph; 278 | int i = 0; 279 | for (Agnode_t *ag_node = agfstnode(_graph); ag_node != NULL; 280 | ag_node = agnxtnode(_graph, ag_node)) { 281 | GVLNode *node = [[GVLNode alloc] init]; 282 | node.node = ag_node; 283 | node.parent = _graph; 284 | node.label = [node getAttributeForKey:@"label"]; 285 | [_nodes addObject:node]; 286 | [node prepare]; 287 | for (Agedge_t *ag_edge = agfstout(_graph, ag_node); ag_edge != NULL; 288 | ag_edge = agnxtout(_graph, ag_edge)) { 289 | GVLEdge *edge = [[GVLEdge alloc] init]; 290 | edge.edge = ag_edge; 291 | edge.parent = _graph; 292 | [_edges addObject:edge]; 293 | [edge prepare]; 294 | } 295 | i++; 296 | } 297 | return NO; 298 | } 299 | 300 | - (BOOL)applyLayout { 301 | if (gvLayout(_context, _graph, (char *)"dot") == 0) { 302 | for (GVLNode *node in self.nodes) { 303 | [node prepare]; 304 | } 305 | for (GVLEdge *edge in self.edges) { 306 | [edge prepare]; 307 | } 308 | return YES; 309 | } 310 | return NO; 311 | } 312 | 313 | - (CGSize)size { 314 | int width = GD_bb(_graph).UR.x; 315 | int height = GD_bb(_graph).UR.y; 316 | return CGSizeMake(width, height); 317 | } 318 | 319 | - (void)dealloc { 320 | gvFreeLayout(_context, _graph); 321 | agclose(_graph); 322 | gvFreeContext(_context); 323 | // delete graph; 324 | // delete context; 325 | } 326 | 327 | @end 328 | 329 | @implementation GVLUtils 330 | + (float)getHeightForGraph:(Agraph_t *)graph { 331 | return GD_bb(graph).UR.y; 332 | } 333 | 334 | + (NSMutableArray *)toPolygon:(const polygon_t *)poly 335 | width:(float)width 336 | height:(float)height { 337 | NSMutableArray *polygon = [NSMutableArray array]; 338 | if (poly->peripheries != 1) 339 | NSLog(@"unsupported number of peripheries %d", poly->peripheries); 340 | 341 | const int sides = poly->sides; 342 | const pointf *vertices = poly->vertices; 343 | for (int side = 0; side < sides; side++) { 344 | CGPoint point = CGPointMake(vertices[side].x + width / 2, 345 | vertices[side].y + height / 2); 346 | [polygon addObject:[NSValue valueWithCGPoint:point]]; 347 | } 348 | return polygon; 349 | } 350 | 351 | + (CGPathRef)toPathWithType:(const char *)type 352 | poly:(const polygon_t *)poly 353 | width:(float)width 354 | height:(float)height { 355 | if ((strcmp(type, "rectangle") == 0) || (strcmp(type, "box") == 0) || 356 | (strcmp(type, "hexagon") == 0) || (strcmp(type, "polygon") == 0) || 357 | (strcmp(type, "diamond") == 0) || (strcmp(type, "Mdiamond") == 0) || 358 | (strcmp(type, "Msquare") == 0) || (strcmp(type, "star") == 0)) { 359 | NSMutableArray *points = 360 | [GVLUtils toPolygon:poly width:width height:height]; 361 | [points addObject:[points firstObject]]; 362 | return [GVLUtils toPath:points]; 363 | } else if ((strcmp(type, "ellipse") == 0) || 364 | (strcmp(type, "circle") == 0)) { 365 | NSMutableArray *points = 366 | [GVLUtils toPolygon:poly width:width height:height]; 367 | CGPoint p1 = [points[0] CGPointValue]; 368 | CGPoint p2 = [points[1] CGPointValue]; 369 | CGRect rect = CGRectMake(p1.x, p1.y, p2.x, p2.y); 370 | return CGPathCreateWithEllipseInRect(rect, NULL); 371 | } else { 372 | NSLog(@"Unsupported shape %s", type); 373 | } 374 | return NULL; 375 | } 376 | 377 | + (CGPathRef)toPathWithSplines:(const splines *)spl height:(float)height { 378 | CGMutablePathRef path = CGPathCreateMutable(); 379 | if ((spl->list != 0) && (spl->list->size % 3 == 1)) { 380 | bezier bez = spl->list[0]; 381 | // If there is a starting point, draw a line from it to the first curve 382 | // point 383 | if (bez.sflag) { 384 | CGPoint p1 = [GVLUtils toPointF:bez.sp height:height]; 385 | CGPathMoveToPoint(path, NULL, p1.x, p1.y); 386 | CGPoint p2 = [GVLUtils toPointF:bez.list[0] height:height]; 387 | CGPathAddLineToPoint(path, NULL, p2.x, p2.y); 388 | } else { 389 | CGPoint p = [GVLUtils toPointF:bez.list[0] height:height]; 390 | CGPathMoveToPoint(path, NULL, p.x, p.y); 391 | } 392 | // Loop over the curve points 393 | for (int i = 1; i < bez.size; i += 3) { 394 | CGPoint p1 = [GVLUtils toPointF:bez.list[i] height:height]; 395 | CGPoint p2 = [GVLUtils toPointF:bez.list[i + 1] height:height]; 396 | CGPoint p3 = [GVLUtils toPointF:bez.list[i + 2] height:height]; 397 | CGPathAddCurveToPoint(path, NULL, p1.x, p1.y, p2.x, p2.y, p3.x, 398 | p3.y); 399 | } 400 | 401 | // If there is an ending point, draw a line to it 402 | if (bez.eflag) { 403 | CGPoint p = [GVLUtils toPointF:bez.ep height:height]; 404 | CGPathMoveToPoint(path, NULL, p.x, p.y); 405 | } 406 | } 407 | return path; 408 | } 409 | 410 | + (CGPathRef)toPath:(NSArray *)points { 411 | CGMutablePathRef path = CGPathCreateMutable(); 412 | CGPoint start = [[points firstObject] CGPointValue]; 413 | CGPathMoveToPoint(path, NULL, start.x, start.y); 414 | for (int i = 1; points.count > i; i++) { 415 | CGPoint point = [points[i] CGPointValue]; 416 | CGPathAddLineToPoint(path, NULL, point.x, point.y); 417 | } 418 | return path; 419 | } 420 | 421 | + (CGPoint)toPointF:(pointf)p height:(float)height { 422 | return CGPointMake(p.x, height - p.y); 423 | } 424 | 425 | + (CGPoint)toPoint:(point)p height:(float)height { 426 | return CGPointMake(p.x, height - p.y); 427 | } 428 | 429 | + (CGPoint)centerToOrigin:(CGPoint)point 430 | width:(float)width 431 | height:(float)height { 432 | return CGPointMake(point.x - width / 2, point.y - height / 2); 433 | } 434 | 435 | + (CGColorRef)toColor:(NSString *)name { 436 | UIColor *color = [UIColor colorNamed:name]; 437 | return color.CGColor; 438 | } 439 | 440 | + (UIBezierPath *)arrowFrom:(CGPoint)start 441 | to:(CGPoint)end 442 | tailWidth:(CGFloat)tailWidth 443 | headWidth:(CGFloat)headWidth 444 | headLength:(CGFloat)headLength { 445 | 446 | CGFloat length = hypotf(end.x - start.x, end.y - start.y); 447 | CGFloat tailLength = length - headLength; 448 | 449 | CGPoint points[7]; 450 | 451 | points[0] = CGPointMake(0, tailWidth / 2); 452 | points[1] = CGPointMake(tailLength, tailWidth / 2); 453 | points[2] = CGPointMake(tailLength, headWidth / 2); 454 | points[3] = CGPointMake(length, 0); 455 | points[4] = CGPointMake(tailLength, -headWidth / 2); 456 | points[5] = CGPointMake(tailLength, -tailWidth / 2); 457 | points[6] = CGPointMake(0, -tailWidth / 2); 458 | 459 | CGFloat cosine = (end.x - start.x) / length; 460 | CGFloat sine = (end.y - start.y) / length; 461 | 462 | CGAffineTransform transform = 463 | CGAffineTransformMake(cosine, sine, -sine, cosine, start.x, start.y); 464 | 465 | CGMutablePathRef cgPath = CGPathCreateMutable(); 466 | CGPathAddLines(cgPath, &transform, points, sizeof points / sizeof *points); 467 | 468 | UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:cgPath]; 469 | [bezierPath closePath]; 470 | CGPathRelease(cgPath); 471 | return bezierPath; 472 | } 473 | 474 | @end 475 | 476 | @implementation GVLConfig 477 | + (float)dpi { 478 | return _dpi; 479 | } 480 | + (void)setDpi:(float)value { 481 | _dpi = value; 482 | } 483 | @end 484 | -------------------------------------------------------------------------------- /GraphLayout/lib/libcdt.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libcdt.a -------------------------------------------------------------------------------- /GraphLayout/lib/libcgraph.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libcgraph.a -------------------------------------------------------------------------------- /GraphLayout/lib/libgvc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libgvc.a -------------------------------------------------------------------------------- /GraphLayout/lib/libgvplugin_core.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libgvplugin_core.a -------------------------------------------------------------------------------- /GraphLayout/lib/libgvplugin_dot_layout.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libgvplugin_dot_layout.a -------------------------------------------------------------------------------- /GraphLayout/lib/libpathplan.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libpathplan.a -------------------------------------------------------------------------------- /GraphLayout/lib/libxdot.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/GraphLayout/lib/libxdot.a -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Bakhtiyor Khodjaev 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraphLayout 2 | 3 | [![Version](https://img.shields.io/cocoapods/v/GraphLayout.svg?style=flat)](http://cocoapods.org/pods/GraphLayout) 4 | [![License](https://img.shields.io/cocoapods/l/GraphLayout.svg?style=flat)](http://cocoapods.org/pods/GraphLayout) 5 | [![Platform](https://img.shields.io/cocoapods/p/GraphLayout.svg?style=flat)](http://cocoapods.org/pods/GraphLayout) 6 | 7 | 8 | GraphLayout - UI controls for graph visualization. It is powered by Graphviz. Graph visualization is a way of representing structural information as diagrams of abstract graphs and networks. It has important applications in networking, bioinformatics, software engineering, database and web design, machine learning, and in visual interfaces for other technical domains. 9 | 10 | ## Example 11 | 12 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 13 | Screenshot1 14 | 15 | ## Requirements 16 | Xcode 9, iOS 11 17 | 18 | ## Installation 19 | 20 | GraphLayout is available through [CocoaPods](http://cocoapods.org). To install 21 | it, simply add the following line to your Podfile: 22 | 23 | ```ruby 24 | pod 'GraphLayout' 25 | ``` 26 | Notice, please, GraphLayout doesn't support frameworks. 27 | 28 | ## Usage 29 | Create graph, add nodes and edges. 30 | ```swift 31 | let graph:Graph = Graph() 32 | let node1 = graph.addNode("node 1") 33 | let node2 = graph.addNode("node 2") 34 | let node3 = graph.addNode("node 3") 35 | let _ = graph.addEdge(from: node1, to: node2) 36 | let _ = graph.addEdge(from: node1, to: node3) 37 | let _ = graph.addEdge(from: node3, to: node2) 38 | ``` 39 | Apply graph layout (Graphviz powered) 40 | ```swift 41 | graph.applyLayout() 42 | ``` 43 | 44 | ### GraphView 45 | GraphView is a view to draw graphs. Set graph property of GraphView. 46 | ```swift 47 | graphView.graph = graph 48 | graphView.setNeedsDisplay() 49 | ``` 50 | 51 | ### GraphLayout 52 | GraphLayout is UICollectionView layout and data source to display graphs. 53 | ```swift 54 | let layout = GraphLayout() 55 | layout.graph = graph 56 | layout.setup(collectionView: collectionView) 57 | layout.invalidateLayout() 58 | ``` 59 | 60 | ## Credits 61 | 62 | * Steve D. Lazaro [How-to: Use Graphviz to Draw Graphs in a Qt Graphics Scene](http://www.mupuf.org/blog/2010/07/08/how_to_use_graphviz_to_draw_graphs_in_a_qt_graphics_scene/) 63 | * [qgv](https://github.com/nbergont/qgv) by [nbergont](https://github.com/nbergont) 64 | 65 | ## License 66 | 67 | GraphLayout is available under the MIT license. See the LICENSE file for more info. 68 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /docs/images/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/docs/images/screenshot1.png -------------------------------------------------------------------------------- /docs/images/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakhtiyork/GraphLayout/c65a9f091f67d3952d4a7336b4f23cac7716218a/docs/images/screenshot2.png --------------------------------------------------------------------------------