Skip to content

Repository files navigation

SwiftKLine

一个轻量级、模块化且易于扩展的 K 线图表框架,专为 Swift 应用设计。

功能特点

核心架构

  • 模块化设计:数据加载、指标计算、渲染协调、交互和样式分层管理。
  • 高性能渲染:复用 renderer、缓存 legend、合并 redraw,并支持实时 tick 增量更新。
  • 扩展友好:可注册指标 renderer,支持自定义样式、主题和指标 key。
  • 协议驱动:通过 ChartItemProvider 接入历史分页、区间补数和实时流。
  • Swift 6 友好:数据提供者和 K 线数据模型要求 Sendable,加载流程使用 actor 隔离。

已实现功能

  • K 线蜡烛图绘制(阳线 / 阴线)
  • 手势交互(缩放、平移、十字线)
  • 实时数据订阅
  • 主指标:MA、EMA、WMA、BOLL、SAR
  • 副指标:MACD、RSI、VOL
  • 分时图模式
  • 自定义渲染器
  • 主题配置
  • 指标选择持久化
  • 更多高级指标(持续迭代中)

快速开始

安装

直接将 Sources/SwiftKLine 目录添加到工程,或在 Swift Package Manager 中引用本仓库。

目前项目处于早期阶段,后续版本可能包含破坏性更改,请谨慎使用。

基本使用

通过 ChartOptions 配置图表行为,ChartView 负责渲染;数据提供者通过 loadData(using:) 显式绑定或替换:

import UIKit
import SwiftKLine
letprovider=BinanceDataProvider(symbol:"BTCUSDT", period:.m1)letoptions=ChartOptions(
appearance:.theme(.midnight),
content:.candlestick,
indicators:IndicatorSelectionState(
mainIndicatorIDs:[.ma],
subIndicatorIDs:[.vol,.macd]),
features:[.liveUpdates,.gapRecovery,.indicatorPersistence],
plugins:.default
)letchartView=ChartView(options: options)
chartView.loadData(using: provider)
view.addSubview(chartView)
  • ChartItemProvider 负责提供分页历史数据、按时间区间补数以及实时流。
  • 框架内置 ChartItemLoader,会在前后台切换时自动补齐缺失区间。
  • loadData(using:) 会重置当前数据、指标序列和分页状态,并启动新的 loader。
  • ChartOptions 负责图表装配;loadData(using:) 负责绑定或替换数据提供者。保留这两个步骤可以在周期切换、provider 替换和视图复用时保持行为明确。

切换主图样式

chartView.setContentStyle(.candlestick)
chartView.setContentStyle(.timeSeries)

ChartType 当前支持:

  • .candlestick:蜡烛图主图。
  • .timeSeries:分时图主图。

创建自定义数据源

实现 ChartItemProvider 即可接入任意行情源:

finalclassMyProvider:ChartItemProvider,@uncheckedSendable{func fetchChartItems(forPage page:Int)asyncthrows->[anyChartItem]{ /* ... */ }func fetchChartItems(from start:Date, to end:Date)asyncthrows->[anyChartItem]{ /* ... */ }func liveStream()->AsyncStream<anyChartItem>{ /* 可选 */ }}

说明:

  • page == 0 表示最近一页,page 递增表示继续向更早历史分页。
  • fetchChartItems(from:to:) 用于前后台切换、网络恢复等场景的缺口补齐。
  • liveStream() 默认返回空流;只有需要实时行情时才需要实现。
  • Provider 必须是 AnyObject & Sendable。如果内部使用锁、actor 或不可变状态保证线程安全,可按需使用 @unchecked Sendable

K 线数据模型需实现 ChartItem

structCandle:ChartItem{letopen:Doubleletclose:Doublelethigh:Doubleletlow:Doubleletvolume:Doubleletvalue:Doublelettimestamp:Int // 秒级时间戳
}

指标选择持久化

ChartView 默认使用 UserDefaultsIndicatorSelectionStore 保存主/副图指标选择。可以注入自定义 store,或传入 nil 关闭持久化:

letview=ChartView(indicatorSelectionStore:nil)

监听指标变化:

chartView.indicatorSelectionChanged ={ state inprint(state.mainIndicators, state.subIndicators)}

恢复默认指标:

chartView.resetIndicatorsToDefault()

配置与主题

使用内置主题

letdark=ChartConfiguration.themed(.midnight)letlight=ChartConfiguration.themed(.solaris)letchartView=ChartView(configuration: dark)

自定义配置

letconfiguration=ChartConfiguration(
candleStyle:CandleStyle(
risingColor:.systemGreen,
fallingColor:.systemRed,
width:8,
gap:2),
watermarkText:"SwiftKLine",
layoutMetrics:LayoutMetrics(
mainChartHeight:320,
timelineHeight:16,
indicatorHeight:72,
indicatorSelectorHeight:34),
defaultMainIndicators:[.ma],
defaultSubIndicators:[.vol,.macd])

扩展框架

扩展内置指标渲染

通过 PluginRegistryregisterRenderer(placement:provider:) 可为指定位置注册额外的渲染器。

letregistry=PluginRegistry.default
registry.registerRenderer(placement:.overlay){ _, configuration in[MyOverlayRenderer()]}letoptions=ChartOptions(plugins: registry)

使用已存在的 IndicatorID 注册插件时,会替换当前 PluginRegistry 实例中的旧插件,并返回被替换的插件。不同 chart view 需要不同插件集合时,请使用独立的 registry 实例。

兼容旧 API

ChartOptions 是主要图表装配对象,ChartConfiguration 是视觉和内置指标展示配置对象。loadData(using:)setContentStyle(_:)resetIndicatorsToDefault() 等命令式 API 仍可用。

API 命名说明

  • ChartOptions 是主要图表装配对象。
  • ChartConfiguration 是视觉和内置指标展示配置对象。
  • 新代码优先使用 IndicatorSelectionState(mainIndicatorIDs:subIndicatorIDs:),不要优先使用 main/sub 标签。
  • ChartItem.timestamp 必须是 Unix 秒级时间戳;timestampSeconds 别名用于提高可读性。

自定义指标插件

通过 IndicatorPluginIndicatorCalculator 协议,可以在不修改内置 BuiltInIndicator 的前提下新增完整指标:

structMyCalculator:IndicatorCalculator{letid=SeriesKey(indicatorID:"custom.myIndicator", name:"MY")func calculate(for items:[anyChartItem])->[Double?]{
items.map{Optional($0.close)}}}structMyPlugin:IndicatorPlugin{letid:IndicatorID="custom.myIndicator"lettitle="MY"letplacement:IndicatorPlacement=.overlay
letdefaultSeriesKeys=[SeriesKey(indicatorID:"custom.myIndicator", name:"MY")]func makeCalculators(configuration:ChartConfiguration)->[anyIndicatorCalculator]{[MyCalculator()]}@MainActorfunc makeRenderers(configuration:ChartConfiguration)->[anyChartRenderer]{[MyRenderer()]}}letregistry=PluginRegistry.default
registry.register(MyPlugin())letoptions=ChartOptions(plugins: registry)

许可证

本项目采用 MIT 许可证 - 详情请见 LICENSE 文件。

About

轻量级 iOS K 线图表框架,基于现代 Swift 与模块化架构打造,高性能且易扩展维护

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages