diff --git a/Examples/ForceDirectedGraph3D/ForceDirectedGraph3D/ContentView.swift b/Examples/ForceDirectedGraph3D/ForceDirectedGraph3D/ContentView.swift index ec6644f..3a375d9 100644 --- a/Examples/ForceDirectedGraph3D/ForceDirectedGraph3D/ContentView.swift +++ b/Examples/ForceDirectedGraph3D/ForceDirectedGraph3D/ContentView.swift @@ -44,7 +44,11 @@ func buildSimulation() -> Simulation3D { forceField: My3DForce() ) +<<<<<<< HEAD for _ in 0..<720 { +======= + for i in 0..<720 { +>>>>>>> main sim.tick() } return sim diff --git a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample.xcodeproj/project.pbxproj b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample.xcodeproj/project.pbxproj index 52f9ae0..4217179 100644 --- a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample.xcodeproj/project.pbxproj +++ b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample.xcodeproj/project.pbxproj @@ -11,7 +11,11 @@ B70B52AF2AF822FF00A1E6CD /* Grape in Frameworks */ = {isa = PBXBuildFile; productRef = B70B52AE2AF822FF00A1E6CD /* Grape */; }; B71759592AFBFC4B000DF006 /* Miserables.swift in Sources */ = {isa = PBXBuildFile; fileRef = B71759582AFBFC4B000DF006 /* Miserables.swift */; }; B717595B2AFBFDBD000DF006 /* Lattice.swift in Sources */ = {isa = PBXBuildFile; fileRef = B717595A2AFBFDBD000DF006 /* Lattice.swift */; }; +<<<<<<< HEAD B762092F2B49FCD000476B93 /* MermaidVisualization.swift in Sources */ = {isa = PBXBuildFile; fileRef = B762092E2B49FCD000476B93 /* MermaidVisualization.swift */; }; +======= + B719E4112AE5FBFC009D6C24 /* ForceDirectedLatticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B719E4102AE5FBFC009D6C24 /* ForceDirectedLatticeView.swift */; }; +>>>>>>> main B780DD7A2AF84ECB001C605F /* MyRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B780DD792AF84ECB001C605F /* MyRing.swift */; }; B7AFA55B2ADF4997009C7154 /* ForceDirectedGraphExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7AFA55A2ADF4997009C7154 /* ForceDirectedGraphExampleApp.swift */; }; B7AFA55D2ADF4997009C7154 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7AFA55C2ADF4997009C7154 /* ContentView.swift */; }; @@ -24,7 +28,11 @@ /* Begin PBXFileReference section */ B71759582AFBFC4B000DF006 /* Miserables.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Miserables.swift; sourceTree = ""; }; B717595A2AFBFDBD000DF006 /* Lattice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lattice.swift; sourceTree = ""; }; +<<<<<<< HEAD B762092E2B49FCD000476B93 /* MermaidVisualization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MermaidVisualization.swift; sourceTree = ""; }; +======= + B719E4102AE5FBFC009D6C24 /* ForceDirectedLatticeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForceDirectedLatticeView.swift; sourceTree = ""; }; +>>>>>>> main B780DD792AF84ECB001C605F /* MyRing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyRing.swift; sourceTree = ""; }; B7AFA5572ADF4997009C7154 /* ForceDirectedGraphExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ForceDirectedGraphExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; B7AFA55A2ADF4997009C7154 /* ForceDirectedGraphExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForceDirectedGraphExampleApp.swift; sourceTree = ""; }; @@ -69,6 +77,10 @@ isa = PBXGroup; children = ( B780DD792AF84ECB001C605F /* MyRing.swift */, +<<<<<<< HEAD +======= + B719E4102AE5FBFC009D6C24 /* ForceDirectedLatticeView.swift */, +>>>>>>> main B7AFA55A2ADF4997009C7154 /* ForceDirectedGraphExampleApp.swift */, B7AFA55C2ADF4997009C7154 /* ContentView.swift */, B7AFA55E2ADF4999009C7154 /* Assets.xcassets */, @@ -77,7 +89,10 @@ B7AFA56E2ADF49D6009C7154 /* Data.swift */, B71759582AFBFC4B000DF006 /* Miserables.swift */, B717595A2AFBFDBD000DF006 /* Lattice.swift */, +<<<<<<< HEAD B762092E2B49FCD000476B93 /* MermaidVisualization.swift */, +======= +>>>>>>> main ); path = ForceDirectedGraphExample; sourceTree = ""; @@ -171,8 +186,12 @@ B717595B2AFBFDBD000DF006 /* Lattice.swift in Sources */, B780DD7A2AF84ECB001C605F /* MyRing.swift in Sources */, B7AFA55D2ADF4997009C7154 /* ContentView.swift in Sources */, + B719E4112AE5FBFC009D6C24 /* ForceDirectedLatticeView.swift in Sources */, B7AFA56F2ADF49D6009C7154 /* Data.swift in Sources */, +<<<<<<< HEAD B762092F2B49FCD000476B93 /* MermaidVisualization.swift in Sources */, +======= +>>>>>>> main B71759592AFBFC4B000DF006 /* Miserables.swift in Sources */, B7AFA55B2ADF4997009C7154 /* ForceDirectedGraphExampleApp.swift in Sources */, ); diff --git a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/ContentView.swift b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/ContentView.swift index f1a72af..9f779b1 100644 --- a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/ContentView.swift +++ b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/ContentView.swift @@ -71,9 +71,14 @@ enum ExampleKind { case ring case classicMiserable case lattice +<<<<<<< HEAD case mermaid static let list: [ExampleKind] = [.ring, .classicMiserable, .lattice, .mermaid] +======= + + static let list: [ExampleKind] = [.ring, .classicMiserable, .lattice] +>>>>>>> main } extension ExampleKind { @@ -85,8 +90,11 @@ extension ExampleKind { return "Miserables" case .lattice: return "Lattice" +<<<<<<< HEAD case .mermaid: return "Mermaid visualization" +======= +>>>>>>> main } } } @@ -108,8 +116,11 @@ struct ContentView: View { MiserableGraph() case .lattice: Lattice() +<<<<<<< HEAD case .mermaid: MermaidVisualization() +======= +>>>>>>> main } } } diff --git a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Lattice.swift b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Lattice.swift index 1a088fb..0338518 100644 --- a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Lattice.swift +++ b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Lattice.swift @@ -33,25 +33,44 @@ struct Lattice: View { @inlinable var body: some View { ForceDirectedGraph($isRunning) { +<<<<<<< HEAD Repeated(0..<(width*width)) { i in let _i = Double(i / width) / Double(width) let _j = Double(i % width) / Double(width) +======= + ForEach(Array(0..<(width*width)), id:\.self) { i in + + let _i = Double(i / width) / Double(width) + let _j = Double(i % width) / Double(width) + +>>>>>>> main NodeMark(id: i, radius: 3.0) .foregroundStyle(Color(red: 1, green: _i, blue: _j)) .stroke() } +<<<<<<< HEAD Repeated(edge) { LinkMark(from: $0.0, to: $0.1) } +======= + for l in edge { + + LinkMark(from: l.0, to: l.1) + } +>>>>>>> main } force: { LinkForce( originalLength: .constant(0.8), stiffness: .weightedByDegree(k: { _, _ in 1}) ) ManyBodyForce(strength: -0.8) +<<<<<<< HEAD +======= + +>>>>>>> main } .toolbar { Button { @@ -61,6 +80,9 @@ struct Lattice: View { Text(isRunning ? "Pause" : "Start") } } +<<<<<<< HEAD +======= +>>>>>>> main } } diff --git a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Miserables.swift b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Miserables.swift index 6f45d36..7ce6982 100644 --- a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Miserables.swift +++ b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/Miserables.swift @@ -1,5 +1,9 @@ // +<<<<<<< HEAD // Miserables.swift +======= +// ForceDirectedGraphSwiftUIExample.swift +>>>>>>> main // ForceDirectedGraphExample // // Created by li3zhen1 on 11/5/23. @@ -8,6 +12,7 @@ import Foundation import Grape import SwiftUI +<<<<<<< HEAD import Charts @@ -49,6 +54,62 @@ struct MiserableGraph: View { LinkMark(from: l.source, to: l.target) } // +======= +import ForceSimulation +import Charts + + +//struct MyForceField: ForceField { +// +// typealias Vector = SIMD2 +// +// public var force = CompositedForce { +// LinkForce( +// originalLength: .constant(20.0), +// stiffness: .weightedByDegree(k: { _, _ in 3.0}) +// ) +// CenterForce() +// ManyBodyForce(strength: -15) +// } +//} + + + +struct MiserableGraph: View { + + @State var isRunning = false + let graphData = getData(miserables) + + var body: some View { + ForceDirectedGraph($isRunning) { + + for l in graphData.links { + let fromID = graphData.nodes.firstIndex { mn in + mn.id == l.source + }! + let toID = graphData.nodes.firstIndex { mn in + mn.id == l.target + }! + LinkMark(from: fromID, to: toID) + } + ForEach(graphData.nodes.indices, id: \.self) { i in + NodeMark(id: i) + .symbol(.asterisk) + .symbolSize(radius: 12.0) + .foregroundStyle( + colors[graphData.nodes[i].group % colors.count] + .shadow(.inner(color:colors[graphData.nodes[i].group % colors.count].opacity(0.3), radius: 3, x:0, y: 1.5)) + .shadow(.drop(color:colors[graphData.nodes[i].group % colors.count].opacity(0.12), radius: 12, x:0, y: 8)) + ) + .stroke() + .label(offset: CGVector(dx: 0.0, dy: 12.0)) { +// if i.isMultiple(of: 5) { + Text(graphData.nodes[i].id) + .font(.title3) +// } + } + } +>>>>>>> main } force: { ManyBodyForce(strength: -20) LinkForce( @@ -56,6 +117,7 @@ struct MiserableGraph: View { stiffness: .weightedByDegree(k: { _, _ in 1.0}) ) CenterForce() +<<<<<<< HEAD } .onNodeTapped { node in inspectorPresented = true @@ -72,6 +134,16 @@ struct MiserableGraph: View { if opacity < 1 { opacity = 1 } +======= +// CollideForce() + } + .onNodeTapped { + print($0) + } + .toolbar { + Button { + isRunning = !isRunning +>>>>>>> main } label: { Image(systemName: isRunning ? "pause.fill" : "play.fill") Text(isRunning ? "Pause" : "Start") diff --git a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/MyRing.swift b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/MyRing.swift index db4f377..0d33565 100644 --- a/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/MyRing.swift +++ b/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/MyRing.swift @@ -35,7 +35,11 @@ struct MyRing: View { ForceDirectedGraph($isRunning) { +<<<<<<< HEAD Repeated(0..<20) { i in +======= + ForEach(Array(0..<20), id: \.self) { i in +>>>>>>> main NodeMark(id: 3 * i + 0) .symbol(.circle) .symbolSize(radius:4.0) @@ -49,6 +53,7 @@ struct MyRing: View { .symbolSize(radius:6.0) .foregroundStyle(.yellow) +<<<<<<< HEAD LinkMark(from: 3 * i + 0, to: 3 * i + 1) @@ -58,6 +63,14 @@ struct MyRing: View { LinkMark(from: 3 * i + 1, to: 3 * ((i + 1) % 20) + 1) LinkMark(from: 3 * i + 2, to: 3 * ((i + 1) % 20) + 2) +======= + LinkMark(from: 3 * i + 0, to: 3 * i + 1) + LinkMark(from: 3 * i + 1, to: 3 * i + 2) + + for j in 0..<3 { + LinkMark(from: 3 * i + j, to: 3 * ((i + 1) % 20) + j) + } +>>>>>>> main } } force: { ManyBodyForce(strength: -15) diff --git a/README.md b/README.md index d6f21a9..a007254 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ struct MyGraph: View { @State var isRunning = true // start moving once appeared. var body: some View { +<<<<<<< HEAD ForceDirectedGraph(isRunning: $isRunning) { // Declare nodes and links like you would do in Swift Charts. @@ -97,6 +98,20 @@ struct MyGraph: View { } } forceField: { +======= + ForceDirectedGraph($isRunning) { + + // Declare nodes and links like you would do in Swift Charts. + NodeMark(id: 0).foregroundStyle(.green) + NodeMark(id: 1).foregroundStyle(.blue) + NodeMark(id: 2).foregroundStyle(.yellow) + + ForEach(Array(0..<2), id:\.self) { i in + LinkMark(from: i, to: i+1) + } + + } force: { +>>>>>>> main LinkForce() CenterForce() ManyBodyForce() diff --git a/Sources/ForceSimulation/Forces/RadialForce.swift b/Sources/ForceSimulation/Forces/RadialForce.swift index 729c99e..8c32a4c 100644 --- a/Sources/ForceSimulation/Forces/RadialForce.swift +++ b/Sources/ForceSimulation/Forces/RadialForce.swift @@ -22,7 +22,6 @@ extension Kinetics { var calculatedStrength: UnsafeArray! = nil - @inlinable public func apply(to kinetics: inout Kinetics) { let alpha = kinetics.alpha diff --git a/Sources/Grape/Modifiers/Effects/GrapeEffect.ForegroundStyle.swift b/Sources/Grape/Modifiers/Effects/GrapeEffect.ForegroundStyle.swift index c1fc803..b8e8eaa 100644 --- a/Sources/Grape/Modifiers/Effects/GrapeEffect.ForegroundStyle.swift +++ b/Sources/Grape/Modifiers/Effects/GrapeEffect.ForegroundStyle.swift @@ -54,7 +54,6 @@ extension GraphContentEffect.ForegroundStyle: GraphContentModifier { } } - extension GraphContentEffect.Shading: GraphContentModifier { @inlinable public func _into(