Skip to content

Commit 62f172a

Browse files
committed
Add evolution dendrogram chart sample
Introduce an Evolution Dendrogram sample: add evolutionDendrogram.json as a data resource and register it in the Xcode project. Add AATreegraphChartComposer:evolutionDendrogramChart which configures the treegraph series, injects icon CSS via before-draw JS, and sets chart/axis/tooltip options. Add AAOptionsData:evolutionDendrogramData to load and sanitize inline SVG strings (escape backslashes and quotes) so SVG icons survive the JS bridge. Minor sample controller/project updates to include the new sample.
1 parent 92f27ef commit 62f172a

10 files changed

Lines changed: 227 additions & 3 deletions

File tree

AAChartKit-ProDemo.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
84B13F4E28A0BA26007356C6 /* AARelationshipChartVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 84B13F4D28A0BA26007356C6 /* AARelationshipChartVC.m */; };
145145
84B13F5128A0BA3A007356C6 /* AABubbleChartVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 84B13F5028A0BA3A007356C6 /* AABubbleChartVC.m */; };
146146
84B13F5628A0E028007356C6 /* AAColumnVariantChartComposer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84B13F5528A0E028007356C6 /* AAColumnVariantChartComposer.m */; };
147+
84C95A832F8CC89400E4A41A /* evolutionDendrogram.json in Resources */ = {isa = PBXBuildFile; fileRef = 84C95A822F8CC89400E4A41A /* evolutionDendrogram.json */; };
147148
84D2B65D2978F9FF005BBA80 /* tilemapForAfricaData.json in Resources */ = {isa = PBXBuildFile; fileRef = 84D2B65B2978F9FF005BBA80 /* tilemapForAfricaData.json */; };
148149
84D2B65E2978F9FF005BBA80 /* simpleTilemapData.json in Resources */ = {isa = PBXBuildFile; fileRef = 84D2B65C2978F9FF005BBA80 /* simpleTilemapData.json */; };
149150
84D9045A2CE1A0FF00F75AFF /* AABoost.js in Resources */ = {isa = PBXBuildFile; fileRef = 84D904592CE1A0FF00F75AFF /* AABoost.js */; };
@@ -432,6 +433,7 @@
432433
84B13F5228A0DA32007356C6 /* AAChartKit-Pro.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AAChartKit-Pro.h"; sourceTree = "<group>"; };
433434
84B13F5428A0E028007356C6 /* AAColumnVariantChartComposer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AAColumnVariantChartComposer.h; sourceTree = "<group>"; };
434435
84B13F5528A0E028007356C6 /* AAColumnVariantChartComposer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AAColumnVariantChartComposer.m; sourceTree = "<group>"; };
436+
84C95A822F8CC89400E4A41A /* evolutionDendrogram.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = evolutionDendrogram.json; sourceTree = "<group>"; };
435437
84D2B65B2978F9FF005BBA80 /* tilemapForAfricaData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = tilemapForAfricaData.json; sourceTree = "<group>"; };
436438
84D2B65C2978F9FF005BBA80 /* simpleTilemapData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = simpleTilemapData.json; sourceTree = "<group>"; };
437439
84D904592CE1A0FF00F75AFF /* AABoost.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = AABoost.js; sourceTree = "<group>"; };
@@ -660,6 +662,7 @@
660662
8492D99F2C7499DC007EB8D0 /* calendarHeatmapData.json */,
661663
84903D102DC654740029FE5A /* sunburst2Data.json */,
662664
84903D122DC654880029FE5A /* stellarChartData.json */,
665+
84C95A822F8CC89400E4A41A /* evolutionDendrogram.json */,
663666
);
664667
path = DataJsonFiles;
665668
sourceTree = "<group>";
@@ -1235,6 +1238,7 @@
12351238
1E66D1FB210AF4ED007EAB8C /* AAJSFiles.bundle in Resources */,
12361239
845F42B72E96986500CE65AB /* eulerData2.json in Resources */,
12371240
84D9045A2CE1A0FF00F75AFF /* AABoost.js in Resources */,
1241+
84C95A832F8CC89400E4A41A /* evolutionDendrogram.json in Resources */,
12381242
27EB8A702497C007007E6A6B /* columnpyramidData.json in Resources */,
12391243
84A5690827FD664F00883553 /* arcdiagram2Data.json in Resources */,
12401244
84DEB8B128FADE1600BF9423 /* simpleDependencyWheelData.json in Resources */,

AAChartKit-ProDemo/ChartsDemo/AAChartKit-Pro/Composer/AATreegraphChartComposer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
1717
+ (AAOptions *)treegraph;
1818
+ (AAOptions *)invertedTreegraph;
1919
+ (AAOptions *)treegraphWithBoxLayout;
20+
+ (AAOptions *)evolutionDendrogramChart;
2021

2122
@end
2223

AAChartKit-ProDemo/ChartsDemo/AAChartKit-Pro/Composer/AATreegraphChartComposer.m

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,89 @@ + (AAOptions *)treegraphWithBoxLayout {
222222
]);
223223
}
224224

225+
+ (AAOptions *)evolutionDendrogramChart {
226+
NSString *injectIconStyleJS =
227+
@AAJSFunc((function () {
228+
const styleId = 'aa-evolution-dendrogram-style';
229+
if (document.getElementById(styleId)) {
230+
return;
231+
}
232+
const style = document.createElement('style');
233+
style.id = styleId;
234+
style.textContent = [
235+
'.icon { width: 48px; height: auto; margin: -5px 0; }',
236+
'.icon-light { fill: #ffffff; stroke-width: 20px; stroke: #141414; }',
237+
'.icon-dark { fill: #141414; }'
238+
].join(' ');
239+
document.head.appendChild(style);
240+
})());
241+
242+
NSDictionary *series = @{
243+
@"type": AAChartTypeTreegraph,
244+
@"keys": @[@"parent", @"id", @"name", @"x", @"level", @"custom.iconSVG"],
245+
@"data": [AAOptionsData evolutionDendrogramData],
246+
@"reversed": @YES,
247+
@"marker": @{
248+
@"radius": @0
249+
},
250+
@"link": @{
251+
@"type": @"default",
252+
@"lineWidth": @2,
253+
@"radius": @6
254+
},
255+
@"dataLabels": @[
256+
@{
257+
@"pointFormat": @"{#unless point.node.isLeaf}~{point.x} Mya{/unless}",
258+
@"align": @"left",
259+
@"verticalAlign": @"bottom",
260+
@"style": @{
261+
@"color": @"#8A8F98",
262+
@"fontWeight": @"normal",
263+
@"textOutline": @"3px contrast",
264+
@"whiteSpace": @"nowrap"
265+
}
266+
},
267+
@{
268+
@"pointFormat": @"{#if point.node.isLeaf}{point.custom.iconSVG}<br>{point.name}{/if}",
269+
@"padding": @0,
270+
@"crop": @NO,
271+
@"align": @"center",
272+
@"verticalAlign": @"top",
273+
@"overflow": @"allow",
274+
@"rotation": @0,
275+
@"useHTML": @YES,
276+
@"y": @10,
277+
@"style": @{
278+
@"color": @"#111111",
279+
@"fontSize": @"0.9em",
280+
@"fontWeight": @"bold",
281+
@"textAlign": @"center",
282+
@"whiteSpace": @"nowrap"
283+
}
284+
}
285+
],
286+
@"collapseButton": @{
287+
@"enabled": @NO
288+
}
289+
};
290+
291+
return AAOptions.new
292+
.beforeDrawChartJavaScriptSet(injectIconStyleJS)
293+
.chartSet(AAChart.new
294+
.invertedSet(true)
295+
.marginRightSet(@40)
296+
.marginBottomSet(@140))
297+
.titleSet(AATitle.new
298+
.textSet(@"Evolution dendrogram"))
299+
.xAxisSet(AAXAxis.new
300+
.offsetSet(@40)
301+
.titleSet(AAAxisTitle.new
302+
.textSet(@"Million years ago"))
303+
.reversedSet(false)
304+
.visibleSet(true))
305+
.tooltipSet(AATooltip.new
306+
.enabledSet(false))
307+
.seriesSet(@[series]);
308+
}
309+
225310
@end

AAChartKit-ProDemo/ChartsDemo/AAChartKit-Pro/DataSource/AAOptionsData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ NS_ASSUME_NONNULL_BEGIN
6262

6363
+ (NSArray *)simpleDependencyWheelData;
6464
+ (NSArray *)treegraphData;
65+
+ (NSArray *)evolutionDendrogramData;
6566
+ (NSArray *)germanicLanguageTreeData;
6667
+ (NSArray *)calendarHeatmapData;
6768

AAChartKit-ProDemo/ChartsDemo/AAChartKit-Pro/DataSource/AAOptionsData.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,28 @@ + (NSArray *)treegraphData {
201201
return [self getJsonDataWithJsonFileName:@"treegraphData"];
202202
}
203203

204+
+ (NSArray *)evolutionDendrogramData {
205+
NSArray *rawData = [self getJsonDataWithJsonFileName:@"evolutionDendrogram"];
206+
NSMutableArray *sanitizedData = [NSMutableArray arrayWithCapacity:rawData.count];
207+
208+
for (NSArray *row in rawData) {
209+
NSMutableArray *mutableRow = [row mutableCopy];
210+
if (mutableRow.count > 5 && [mutableRow[5] isKindOfClass:[NSString class]]) {
211+
NSString *iconSVG = mutableRow[5];
212+
// AAChartView passes options JSON through a JS string literal in demo builds.
213+
// Encode quotes in the inline SVG so this sample survives that bridge unchanged.
214+
iconSVG = [iconSVG stringByReplacingOccurrencesOfString:@"\\"
215+
withString:@"\\u005C"];
216+
iconSVG = [iconSVG stringByReplacingOccurrencesOfString:@"\""
217+
withString:@"\\u0022"];
218+
mutableRow[5] = iconSVG;
219+
}
220+
[sanitizedData addObject:[mutableRow copy]];
221+
}
222+
223+
return [sanitizedData copy];
224+
}
225+
204226
+ (NSArray *)germanicLanguageTreeData {
205227
return [self getJsonDataWithJsonFileName:@"germanicLanguageTreeData"];
206228
}

0 commit comments

Comments
 (0)