Skip to content

Commit 1b56169

Browse files
committed
Add plugin dependency support for chart plugins
Introduces a pluginDependencies property to AAChartView and updates plugin loading logic to accept and merge external plugin dependencies. This allows users to specify custom plugin dependencies, improving flexibility and correctness when loading chart plugins. Demo updated to show usage with AACustom-Stage.js depending on AAXrange.js.
1 parent abb7892 commit 1b56169

File tree

3 files changed

+59
-20
lines changed

3 files changed

+59
-20
lines changed

AAInfographics-Pro/AAChartCreator/AAChartView.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ public class AAChartView: WKWebView {
178178
private var pluginLoader: AAChartViewPluginLoader = ProPluginLoader(provider: ProPluginProvider())
179179

180180
public var userPluginPaths: Set<String> = []
181+
public var pluginDependencies: [String: String] = [:]
181182
#if DEBUG
182183
public var shouldPrintOptionsJSON: Bool = true
183184
#endif
@@ -437,7 +438,11 @@ extension AAChartView: WKUIDelegate {
437438
extension AAChartView: WKNavigationDelegate {
438439
internal func loadAllPluginsAndDrawChart() {
439440
// Load plugins via loader, then draw chart in completion
440-
pluginLoader.loadPluginsIfNeeded(webView: self, userPlugins: userPluginPaths) { [weak self] in
441+
pluginLoader.loadPluginsIfNeeded(
442+
webView: self,
443+
userPlugins: userPluginPaths,
444+
dependencies: pluginDependencies
445+
) { [weak self] in
441446
// Ensure options are ready before drawing
442447
guard let self = self, self.optionsJson != nil else {
443448
self?.debugLog("💀💀💀 AAChartView options not ready after plugin load or view deallocated.")

AAInfographics-Pro/AAChartCreator/AAChartViewPluginProvider.swift

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,12 @@ public protocol AAChartViewPluginLoader {
169169
func configure(options: AAOptions)
170170

171171
/// Loads necessary plugins if they haven't been loaded yet.
172-
func loadPluginsIfNeeded(webView: WKWebView, userPlugins: Set<String>, completion: @escaping () -> Void)
172+
func loadPluginsIfNeeded(
173+
webView: WKWebView,
174+
userPlugins: Set<String>,
175+
dependencies: [String: String],
176+
completion: @escaping () -> Void
177+
)
173178

174179
/// Executes the pre-draw JavaScript script.
175180
func executeBeforeDrawScript(webView: WKWebView)
@@ -187,7 +192,12 @@ public class DefaultPluginLoader: AAChartViewPluginLoader {
187192
// No configuration needed for default
188193
}
189194

190-
public func loadPluginsIfNeeded(webView: WKWebView, userPlugins: Set<String>, completion: @escaping () -> Void) {
195+
public func loadPluginsIfNeeded(
196+
webView: WKWebView,
197+
userPlugins: Set<String>,
198+
dependencies: [String: String],
199+
completion: @escaping () -> Void
200+
) {
191201
#if DEBUG
192202
print("ℹ️ DefaultPluginLoader: No plugins to load.")
193203
#endif
@@ -239,7 +249,12 @@ public class ProPluginLoader: AAChartViewPluginLoader {
239249
}
240250
}
241251

242-
public func loadPluginsIfNeeded(webView: WKWebView, userPlugins: Set<String>, completion: @escaping () -> Void) {
252+
public func loadPluginsIfNeeded(
253+
webView: WKWebView,
254+
userPlugins: Set<String>,
255+
dependencies: [String: String],
256+
completion: @escaping () -> Void
257+
) {
243258
let totalRequiredPluginsSet = requiredPluginPaths.union(userPlugins)
244259
let pluginsToLoad = totalRequiredPluginsSet.subtracting(loadedPluginPaths)
245260

@@ -256,19 +271,23 @@ public class ProPluginLoader: AAChartViewPluginLoader {
256271
}
257272

258273
debugLog("ℹ️ [ProPluginLoader] Preparing to load \(pluginsToLoad.count) new plugin scripts...")
259-
loadAndEvaluateCombinedPluginScript(webView: webView, scriptsToLoad: pluginsToLoad) { [weak self] successfullyLoadedPlugins in
260-
guard let self = self else { return }
261-
self.loadedPluginPaths.formUnion(successfullyLoadedPlugins)
274+
loadAndEvaluateCombinedPluginScript(
275+
webView: webView,
276+
scriptsToLoad: pluginsToLoad,
277+
dependencies: dependencies
278+
) { [weak self] successfullyLoadedPlugins in
279+
guard let self = self else { return }
280+
self.loadedPluginPaths.formUnion(successfullyLoadedPlugins)
262281

263-
#if DEBUG
264-
if successfullyLoadedPlugins.count < pluginsToLoad.count {
265-
print("⚠️ [ProPluginLoader] One or more plugin script files could not be read, or the combined script evaluation failed.")
266-
} else if !successfullyLoadedPlugins.isEmpty {
267-
print("✅ [ProPluginLoader] \(successfullyLoadedPlugins.count) new plugin scripts loaded and evaluated successfully.")
268-
}
269-
print("ℹ️ [ProPluginLoader] Total loaded plugins count: \(self.loadedPluginPaths.count)")
270-
#endif
271-
completion()
282+
#if DEBUG
283+
if successfullyLoadedPlugins.count < pluginsToLoad.count {
284+
print("⚠️ [ProPluginLoader] One or more plugin script files could not be read, or the combined script evaluation failed.")
285+
} else if !successfullyLoadedPlugins.isEmpty {
286+
print("✅ [ProPluginLoader] \(successfullyLoadedPlugins.count) new plugin scripts loaded and evaluated successfully.")
287+
}
288+
print("ℹ️ [ProPluginLoader] Total loaded plugins count: \(self.loadedPluginPaths.count)")
289+
#endif
290+
completion()
272291
}
273292
}
274293

@@ -291,15 +310,23 @@ public class ProPluginLoader: AAChartViewPluginLoader {
291310
// --- Helper methods moved from AAChartView ---
292311

293312
// Helper function to sort plugin paths based on known dependencies
294-
private func sortPluginPaths(_ paths: Set<String>) -> [String] {
313+
private func sortPluginPaths(
314+
_ paths: Set<String>,
315+
merging externalDependencies: [String: String]
316+
) -> [String] {
295317
var sortedPaths = Array(paths)
296-
let dependencies: [String: String] = [
318+
319+
// Base dependencies that are internal to the library
320+
var dependencies: [String: String] = [
297321
"AADependency-Wheel.js": "AASankey.js",
298322
"AAOrganization.js": "AASankey.js",
299323
"AALollipop.js": "AADumbbell.js",
300324
"AATilemap.js": "AAHeatmap.js",
301-
"AAArc-Diagram.js": "AASankey.js" // Added Arc Diagram dependency
325+
"AAArc-Diagram.js": "AASankey.js"
302326
]
327+
328+
// Merge external dependencies, allowing them to override base dependencies if needed
329+
dependencies.merge(externalDependencies) { (_, new) in new }
303330

304331
sortedPaths.sort { path1, path2 in
305332
let file1 = (path1 as NSString).lastPathComponent
@@ -332,14 +359,15 @@ public class ProPluginLoader: AAChartViewPluginLoader {
332359
private func loadAndEvaluateCombinedPluginScript(
333360
webView: WKWebView,
334361
scriptsToLoad: Set<String>,
362+
dependencies: [String: String],
335363
completion: @escaping (Set<String>) -> Void
336364
) {
337365
guard !scriptsToLoad.isEmpty else {
338366
completion(Set())
339367
return
340368
}
341369

342-
let sortedScriptPaths = sortPluginPaths(scriptsToLoad)
370+
let sortedScriptPaths = sortPluginPaths(scriptsToLoad, merging: dependencies)
343371
var combinedJSString = ""
344372
var successfullyReadPaths = Set<String>()
345373

AAInfographics-ProDemo/Demo/AAPlugins/AAStageSeries/AACustomStageChartVC.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ class AACustomStageChartVC: UIViewController {
7070
jsPathCustom_Stage,
7171
]
7272

73+
// 配置它们的依赖关系
74+
self.aaChartView?.pluginDependencies = [
75+
"AACustom-Stage.js": "AAXrange.js"
76+
]
77+
78+
7379
//输出查看 AAOption 的 computedProperties 内容
7480
// AAOptions *aaOptions = [self chartConfigurationWithSelectedIndex:self.selectedIndex];
7581
self.aaOptions = AACustomStageChartComposer.defaultOptions()

0 commit comments

Comments
 (0)