Skip to content

Commit a354936

Browse files
committed
Add organization chart support and Germanic language tree demo
Introduced AAOrganization model and integrated organization chart options into AAPlotOptions. Added AAOrganizationChartComposer and germanicLanguageTreeData.json to demonstrate Germanic language tree visualization. Extended AASeriesElement with nodePadding property and related builder method.
1 parent b14f46e commit a354936

File tree

7 files changed

+200
-0
lines changed

7 files changed

+200
-0
lines changed

AAInfographics-Pro/AAChartCreator/AASeriesElement.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public class AASeriesElement: AAObject {
8282

8383
public var nodes: [Any]?
8484
public var nodeWidth: Float?
85+
public var nodePadding: Float?
8586
public var cursor: String?
8687
public var offset: String? //The offset of an arc diagram nodes column in relation to the plotArea. The offset equal to 50% places nodes in the center of a chart. By default the series is placed so that the biggest node is touching the bottom border of the plotArea. Defaults to '100%'.
8788
public var linkWeight: Int? //The global link weight. If not set, width is calculated per link, depending on the weight value. Defaults to undefined.
@@ -390,6 +391,12 @@ public class AASeriesElement: AAObject {
390391
return self
391392
}
392393

394+
@discardableResult
395+
public func nodePadding(_ prop: Float) -> AASeriesElement {
396+
nodePadding = prop
397+
return self
398+
}
399+
393400
@discardableResult
394401
public func cursor(_ prop: String) -> AASeriesElement {
395402
cursor = prop

AAInfographics-Pro/AAOptionsModel/AAPlotOptions.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class AAPlotOptions: AAObject {
5151
public var treemap: AATreemap?
5252
public var solidgauge: AASolidgauge?
5353
public var pictorial: AAPictorial?
54+
public var organization: AAOrganization?
5455
/*---------------------AAInfogrphics-Pro---------------------*/
5556

5657

@@ -151,6 +152,12 @@ public class AAPlotOptions: AAObject {
151152
pictorial = prop
152153
return self
153154
}
155+
156+
@discardableResult
157+
public func organization(_ prop: AAOrganization) -> AAPlotOptions {
158+
organization = prop
159+
return self
160+
}
154161
/*---------------------AAInfogrphics-Pro---------------------*/
155162

156163

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// AAOrganization.swift
3+
// AAInfographics-ProDemo
4+
//
5+
// Created by AnAn on 2025/9/23.
6+
//
7+
8+
public class AAOrganization: AAObject {
9+
public var hangingIndentTranslation: String?
10+
public var hangingIndent: Float?
11+
12+
@discardableResult
13+
public func hangingIndentTranslation(_ prop: String?) -> AAOrganization {
14+
hangingIndentTranslation = prop
15+
return self
16+
}
17+
18+
@discardableResult
19+
public func hangingIndent(_ prop: Float?) -> AAOrganization {
20+
hangingIndent = prop
21+
return self
22+
}
23+
24+
}

AAInfographics-ProDemo.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@
144144
84DD6C382E8242C400B3D195 /* AAPictorialPaths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DD6C372E8242C400B3D195 /* AAPictorialPaths.swift */; };
145145
84DD6C3B2E8244E000B3D195 /* pictorial2Series.json in Resources */ = {isa = PBXBuildFile; fileRef = 84DD6C3A2E8244E000B3D195 /* pictorial2Series.json */; };
146146
84DD6C3C2E8244E000B3D195 /* pictorial1Series.json in Resources */ = {isa = PBXBuildFile; fileRef = 84DD6C392E8244E000B3D195 /* pictorial1Series.json */; };
147+
84DD6C3E2E8248AB00B3D195 /* AAOrganization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DD6C3D2E8248AB00B3D195 /* AAOrganization.swift */; };
148+
84DD6C402E8249F100B3D195 /* AAOrganizationChartComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DD6C3F2E8249F100B3D195 /* AAOrganizationChartComposer.swift */; };
149+
84DD6C422E824B8D00B3D195 /* germanicLanguageTreeData.json in Resources */ = {isa = PBXBuildFile; fileRef = 84DD6C412E824B8D00B3D195 /* germanicLanguageTreeData.json */; };
147150
84DEB8B628FAE48300BF9423 /* AARelationshipChartVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEB8B528FAE48300BF9423 /* AARelationshipChartVC.swift */; };
148151
84DEB8B828FAE4DF00BF9423 /* AAHeatOrTreeMapChartVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEB8B728FAE4DF00BF9423 /* AAHeatOrTreeMapChartVC.swift */; };
149152
84DEB8BA28FAE4F300BF9423 /* AABubbleChartVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEB8B928FAE4F300BF9423 /* AABubbleChartVC.swift */; };
@@ -320,6 +323,9 @@
320323
84DD6C372E8242C400B3D195 /* AAPictorialPaths.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AAPictorialPaths.swift; sourceTree = "<group>"; };
321324
84DD6C392E8244E000B3D195 /* pictorial1Series.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = pictorial1Series.json; sourceTree = "<group>"; };
322325
84DD6C3A2E8244E000B3D195 /* pictorial2Series.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = pictorial2Series.json; sourceTree = "<group>"; };
326+
84DD6C3D2E8248AB00B3D195 /* AAOrganization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AAOrganization.swift; sourceTree = "<group>"; };
327+
84DD6C3F2E8249F100B3D195 /* AAOrganizationChartComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AAOrganizationChartComposer.swift; sourceTree = "<group>"; };
328+
84DD6C412E824B8D00B3D195 /* germanicLanguageTreeData.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = germanicLanguageTreeData.json; sourceTree = "<group>"; };
323329
84DEB8B528FAE48300BF9423 /* AARelationshipChartVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AARelationshipChartVC.swift; sourceTree = "<group>"; };
324330
84DEB8B728FAE4DF00BF9423 /* AAHeatOrTreeMapChartVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AAHeatOrTreeMapChartVC.swift; sourceTree = "<group>"; };
325331
84DEB8B928FAE4F300BF9423 /* AABubbleChartVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AABubbleChartVC.swift; sourceTree = "<group>"; };
@@ -495,6 +501,7 @@
495501
44D27DB4255A6CE300D0C636 /* DataJsonFiles */ = {
496502
isa = PBXGroup;
497503
children = (
504+
84DD6C412E824B8D00B3D195 /* germanicLanguageTreeData.json */,
498505
843E5E0E2E7AD6390030D36E /* treegraphData.json */,
499506
84A5692927FEC89E00883553 /* arcdiagram1Data.json */,
500507
84A5692A27FEC89E00883553 /* arcdiagram2Data.json */,
@@ -553,6 +560,7 @@
553560
84B13F34289D12DF007356C6 /* AAData.swift */,
554561
84B13F3A289E2CA0007356C6 /* AAParallelAxes.swift */,
555562
84DD6C312E823ECA00B3D195 /* AAPictorial.swift */,
563+
84DD6C3D2E8248AB00B3D195 /* AAOrganization.swift */,
556564
);
557565
path = AAOptionsProModel;
558566
sourceTree = "<group>";
@@ -654,6 +662,7 @@
654662
843E5E0C2E7AD52D0030D36E /* AATreegraphChartComposer.swift */,
655663
84DD6C352E8240EE00B3D195 /* AAPictorialChartComposer.swift */,
656664
84DD6C372E8242C400B3D195 /* AAPictorialPaths.swift */,
665+
84DD6C3F2E8249F100B3D195 /* AAOrganizationChartComposer.swift */,
657666
);
658667
path = Composer;
659668
sourceTree = "<group>";
@@ -794,6 +803,7 @@
794803
843E5E0F2E7AD6390030D36E /* treegraphData.json in Resources */,
795804
84526E0B2CEB401500EB2563 /* AABoost.js in Resources */,
796805
84A5694327FEC89F00883553 /* sunburst2Data.json in Resources */,
806+
84DD6C422E824B8D00B3D195 /* germanicLanguageTreeData.json in Resources */,
797807
84DEB8CA28FAF3C800BF9423 /* volinPlotElement2Data.json in Resources */,
798808
84A5693727FEC89F00883553 /* bigHeatmapData.json in Resources */,
799809
84A5694E27FEC89F00883553 /* arcdiagram3Data.json in Resources */,
@@ -886,6 +896,7 @@
886896
84DD6C382E8242C400B3D195 /* AAPictorialPaths.swift in Sources */,
887897
844615BC283F580300E26DA4 /* AAXAxis.swift in Sources */,
888898
27F872AB25E797690068380F /* ProjectBundlePathLoader.swift in Sources */,
899+
84DD6C402E8249F100B3D195 /* AAOrganizationChartComposer.swift in Sources */,
889900
844615A7283F580300E26DA4 /* AAChart.swift in Sources */,
890901
8446158A283F57C600E26DA4 /* AAChartView.swift in Sources */,
891902
8466E38B2DB1EA8700DBF03B /* ChartListTableViewVC.swift in Sources */,
@@ -953,6 +964,7 @@
953964
844615A8283F580300E26DA4 /* AAStyle.swift in Sources */,
954965
845BABEC2D02D2EB004C15D4 /* OfficialChartSampleVC.swift in Sources */,
955966
84DEB8BC28FAE50500BF9423 /* AAColumnVariantChartVC.swift in Sources */,
967+
84DD6C3E2E8248AB00B3D195 /* AAOrganization.swift in Sources */,
956968
);
957969
runOnlyForDeploymentPostprocessing = 0;
958970
};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//
2+
// AAOrganizationChartComposer.swift
3+
// AAInfographics-ProDemo
4+
//
5+
// Created by AnAn on 2025/9/23.
6+
//
7+
8+
import UIKit
9+
10+
class AAOrganizationChartComposer: NSObject {
11+
12+
static func germanicLanguageTreeChart() -> AAOptions {
13+
let colors: [String] = ["#1e90ff", "#ef476f", "#ffd066", "#04d69f", "#25547c"]
14+
15+
return AAOptions()
16+
.chart(AAChart()
17+
// .height(1200)
18+
.inverted(true))
19+
.title(AATitle()
20+
.text("The Germanic Language Tree"))
21+
// .accessibility(Accessibility()
22+
// .point(AccessibilityPoint()
23+
// .descriptionFormat("{add index 1}. {toNode.id} comes from {fromNode.id}")))
24+
.tooltip(AATooltip()
25+
.outside(true))
26+
27+
.plotOptions(AAPlotOptions()
28+
.organization(AAOrganization()
29+
.hangingIndentTranslation("cumulative")
30+
// Crimp a bit to avoid nodes overlapping lines
31+
.hangingIndent(10)))
32+
33+
.series([
34+
AASeriesElement()
35+
.name("Germanic language tree")
36+
.type(.organization)
37+
.keys(["from", "to"])
38+
.nodeWidth(40)
39+
.nodePadding(20)
40+
.colorByPoint(false)
41+
// .hangingIndentTranslation("cumulative")
42+
// // Crimp a bit to avoid nodes overlapping lines
43+
// .hangingIndent(10)
44+
.levels([
45+
AALevelsElement()
46+
.level(0)
47+
.color("#dedede"),
48+
AALevelsElement()
49+
.level(1)
50+
.color("#dedede"),
51+
AALevelsElement()
52+
.level(2)
53+
.color(colors[3]),
54+
AALevelsElement()
55+
.level(3)
56+
.color(colors[2]),
57+
AALevelsElement()
58+
.level(4)
59+
.color(colors[4])
60+
])
61+
.nodes({
62+
let originalLeafsArr: [String] = [
63+
"Bastarnisch", "Brabantian", "Burgundian", "Crimean Gothic", "Danish",
64+
"Dutch", "English", "Faroese", "Flemish", "Frisian", "Gepidisch", "Gothic",
65+
"Herulisch", "(High) German", "Hollandic", "Icelandic", "Limburgish",
66+
"Low German", "Norwegian", "Rhinelandic", "Rugisch", "Skirisch", "Swedish",
67+
"Vandalic", "Yiddish"
68+
]
69+
70+
var leafs: [[String: Any]] = []
71+
for leaf in originalLeafsArr {
72+
let leafDict: [String: Any] = ["id": leaf, "color": colors[0]]
73+
leafs.append(leafDict)
74+
}
75+
76+
let hangingNodes: [[String: Any]] = [
77+
[
78+
"id": "North Germanic",
79+
"layout": "hanging",
80+
"offsetHorizontal": -15
81+
],
82+
[
83+
"id": "West Germanic",
84+
"layout": "hanging"
85+
],
86+
[
87+
"id": "East Germanic",
88+
"layout": "hanging"
89+
]
90+
]
91+
92+
let nodes = hangingNodes + leafs
93+
return nodes
94+
}())
95+
.data(AAOptionsData.germanicLanguageTreeData)
96+
])
97+
}
98+
}

AAInfographics-ProDemo/Demo/DataSource/AAOptionsData.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ class AAOptionsData {
296296
getJsonDataWithJsonFileName("treegraphData")
297297
}
298298

299+
public class var germanicLanguageTreeData: [Any] {
300+
getJsonDataWithJsonFileName("germanicLanguageTreeData")
301+
}
302+
299303
//https://www.jianshu.com/p/a4b2bd5deca6
300304
private static func getJsonDataWithJsonFileName(_ jsonFileName: String) -> [Any] {
301305
let path = Bundle.main.path(forResource: jsonFileName, ofType: "json")
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
[
2+
["Germanic", "West Germanic"],
3+
["West Germanic", "Old English"],
4+
["Old English", "Middle English"],
5+
["Middle English", "English"],
6+
["West Germanic", "Old Frisian"],
7+
["Old Frisian", "Frisian"],
8+
["West Germanic", "Old Dutch"],
9+
["Old Dutch", "Middle Dutch"],
10+
["Middle Dutch", "Hollandic"],
11+
["Middle Dutch", "Flemish"],
12+
["Middle Dutch", "Dutch"],
13+
["Middle Dutch", "Limburgish"],
14+
["Middle Dutch", "Brabantian"],
15+
["Middle Dutch", "Rhinelandic"],
16+
["West Germanic", "Old Low German"],
17+
["Old Low German", "Middle Low German"],
18+
["Middle Low German", "Low German"],
19+
["West Germanic", "Old High German"],
20+
["Old High German", "Middle High German"],
21+
["Middle High German", "(High) German"],
22+
["Middle High German", "Yiddish"],
23+
24+
["Germanic", "East Germanic"],
25+
["East Germanic", "Gothic"],
26+
["East Germanic", "Vandalic"],
27+
["East Germanic", "Burgundian"],
28+
["East Germanic", "Bastarnisch"],
29+
["East Germanic", "Gepidisch"],
30+
["East Germanic", "Herulisch"],
31+
["East Germanic", "Rugisch"],
32+
["East Germanic", "Skirisch"],
33+
["East Germanic", "Crimean Gothic"],
34+
35+
["Germanic", "North Germanic"],
36+
["North Germanic", "Old Norse"],
37+
["Old Norse", "Old Icelandic"],
38+
["Old Icelandic", "Icelandic"],
39+
["Old Norse", "Old Norwegian"],
40+
["Old Norwegian", "Norwegian"],
41+
["Old Norse", "Faroese"],
42+
["North Germanic", "Old Swedish"],
43+
["Old Swedish", "Middle Swedish"],
44+
["Middle Swedish", "Swedish"],
45+
["North Germanic", "Old Danish"],
46+
["Old Danish", "Middle Danish"],
47+
["Middle Danish", "Danish"]
48+
]

0 commit comments

Comments
 (0)