更新记录
2.0.0(2026-07-19)
在 1.0.0(十万根丝滑手势 + 原生视图直贴)基础上,六件全家桶升级,v1 API 全部兼容(加性、零破坏,v1 契约回归套件锁定 4 冻结黄金图 byte-identical)。14 → 29 引擎 API。
- ① 10 种技术指标 + 多副图:新增 WR(威廉 %R)/ CCI(顺势)/ OBV(能量潮) 副图 + SAR(抛物线转向) 主图叠加;
sub单副图升级为subs数组(最多 3 个副图纵向排列,如 MACD+KDJ+RSI 同屏)。 - ② 画线子系统(8 API):程序化 CRUD(
addDrawing/updateDrawing/removeDrawing/clearDrawings/listDrawings)+ 跨会话存盘(exportDrawings/importDrawings无损,锚点存绝对 (ts,price))+ 命中测试hitTestAt。五种画线:趋势线 / 水平线 / 射线 / 矩形 / 斐波那契回撤。组件 drawMode 手势画线 + 点选拖拽编辑(三端 H5/Android/iOS 对称,@drawingadd/@drawingselect/@drawingchange事件)。 - **③
平台兼容性
uni-app x(5.14)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | 5.0 | 12 | × | × |
nex-kline 专业级 K 线全家桶(自研原生渲染 + 原生视图直贴)
十万根级 K 线丝滑手势,热环路零桥接开销 + 专业行情全家桶:自研原生内核(列式存储 + 周期聚合 + 10 种技术指标 + 多副图 + 视口窗口渲染 + 画线/分时/复权/深度/联动)+ App 端原生视图组件——手势 → 视口 → 渲染 → Bitmap/CALayer 直贴全程原生线程,零桥接开销往返。同一份 自研引擎在 Android / iOS / H5 三端跑出一致输出;纯本地渲染、零网络依赖、不吃 WebView Canvas 性能。
v2.0 六件全家桶:多指标 · 画线 · 分时 · 复权 · 深度 · 联动。v1 API 全部兼容(加性升级、零破坏)。
特性
- 原生视图热环路(卖点):
<uni-nex-kline-view>App 原生视图——单指平移 / 双指捏合缩放 / 单击十字线全在原生层完成,帧循环(AndroidonDrawvsync 合帧 / iOSCADisplayLink-级)里调 原生 渲染出 RGBA 直贴位图,手势零桥接开销,十万根级 K 线丝滑 <nex-kline>统一组件即插即用(easycom 自动注册):三端一套props/事件契约——App 走原生视图、H5 走 canvasputImageData帧循环,业务代码一份- 列式存储 + 事务化装载:SoA 列存(10 万根 ≈ 4.8MB),扁平六元组
[ts,o,h,l,c,v]高速装载 / JSON 兼容入口,整批 OHLC 校验通过才生效(非法数据不污染现有状态) - 周期聚合:
1m/5m/15m/60m/1d按 ts 整除分桶(UTC),停牌缺口自然成稀疏桶;tick(appendCandle/updateLastCandle)尾桶增量重算 - 10 种技术指标 + 多副图(v2):MA / EMA / BOLL / SAR(主图叠加)+ MACD / KDJ / RSI / WR / CCI / OBV(副图,
subs数组最多 3 个纵向排列,如 MACD+KDJ+RSI 同屏)——期望值全部公式手推 + 黄金向量对照,非拍脑袋 - 画线子系统(v2):五种画线(趋势线 / 水平线 / 射线 / 矩形 / 斐波那契回撤)程序化 CRUD + 跨会话存盘(export/import 无损)+ 组件 drawMode 手势画线 + 点选拖拽编辑(
@drawingadd/@drawingselect/@drawingchange);锚点存绝对 (ts,price),切复权/切周期不漂移 - 分时图 + 复权 + 深度 + 联动(v2):
setChartMode('timeshare')分时(收盘连线 + 均价 + 量柱);前/后复权(setAdjustMode+ 除权因子外供);setChartMode('depth')盘口深度阶梯(买绿卖红双轴);多图多周期联动(setCrosshairAt/setViewportByTime+ getMeta 视口 ts) - dpr 真超采样高清:位图按 逻辑×dpr 物理像素渲染,2x/3x 屏不发虚
- 十字线吸附:
getCrosshairData返回命中蜡烛 OHLCV + 各指标值 + 像素锚点(v2 形态按 chartMode 分派:candle/timeshare/depth),组件内置十字线/tooltip - 三端同源:App(Android/iOS) 走 原生绑定层 原生绑定,H5 走同一自研原生内核编译的 H5 端引擎——不是"H5 降级实现"
快速上手
组件(推荐)
<template>
<nex-kline
:engine-id="engineId"
:width-px="360"
:height-px="480"
:revision="revision"
@crosshair="onCrosshair"
@viewportchange="onViewport"
@loadmore="onLoadMore"
/>
</template>
<script>
import {
createKlineEngine, loadCandlesFlat, appendCandle, setPeriod, setIndicators
} from '@/uni_modules/nex-kline'
// #ifdef H5
import { ensureReady } from '@/uni_modules/nex-kline'
// #endif
export default {
data() {
return { engineId: 0, revision: 0 }
},
onReady() {
// #ifdef H5
ensureReady().then(() => { this.boot() })
// #endif
// #ifndef H5
this.boot()
// #endif
},
methods: {
boot() {
const id = createKlineEngine('{"theme":"light","indicators":{"ma":[5,10,20],"sub":"macd"}}')
// 扁平六元组 [ts,o,h,l,c,v] × N(ts 毫秒,严格递增)
loadCandlesFlat(id, [0, 100, 102, 98, 101, 1000, 60000, 101, 105, 100, 104, 1200])
this.engineId = id
this.revision++ // 数据变更 → 组件重渲(revision 刷新协议)
},
pushTick() {
// 实时行情:追加新蜡烛后自增 revision
appendCandle(this.engineId, 120000, 104, 106, 103, 105, 900)
this.revision++
},
onCrosshair(e: string) { /* 十字线 JSON(v2 按 mode 分派):candle/timeshare→{mode,index,ts,OHLC,volume,indicators};depth→{mode:"depth",price,cumBid,cumAsk} */ },
onViewport(e: string) { /* 手势平移/缩放结束的视口元信息 */ },
onLoadMore(e: string) { /* 视口触最左边界 → 可加载更早历史 */ }
}
}
</script>
组件 Props:
| prop | 类型 | 默认 | 说明 |
|---|---|---|---|
engineId |
Number | 必填 | 引擎句柄(createKlineEngine 返回值);0 = 未绑定 |
widthPx / heightPx |
Number | 必填 | 组件尺寸(逻辑像素;内核按设备 dpr 超采样) |
revision |
Number | 0 |
数据版本号:每次改数据后自增 → 组件重渲(组件不轮询引擎) |
crosshairEnabled |
Boolean | true |
单击是否内置显示十字线/tooltip(关掉只发 @crosshair) |
drawMode(v2) |
String | 'none' |
画线模式:'none'(正常 pan/zoom/crosshair)/'trendline'/'horizontal'/'ray'/'rect'/'fib'。优先级 drawMode > crosshair > pan/zoom:非 none 时 tap 落锚点 → 自动 addDrawing;none 时 tap 命中已有画线 → 选中可拖锚点编辑 |
事件:@crosshair(十字线 JSON)、@viewportchange(视口元信息 JSON)、@loadmore(触最左边界,{});v2 画线:@drawingadd(落线完成,新画线 JSON 含 id)、@drawingselect(点选命中已有画线)、@drawingchange(拖锚点编辑后,据此存盘)。
画线工具栏(v2,drawMode + 事件)
<template>
<!-- 工具栏切 drawMode -->
<view class="toolbar">
<button @click="mode='trendline'">趋势线</button>
<button @click="mode='fib'">斐波那契</button>
<button @click="mode='none'">选择/编辑</button>
<button v-if="selectedId>=0" @click="delSelected">删除选中</button>
</view>
<nex-kline :engine-id="engineId" :width-px="360" :height-px="480" :revision="revision"
:draw-mode="mode" @drawingadd="onAdd" @drawingselect="" @drawingchange="onChange" />
</template>
<script>
import { exportDrawings, importDrawings, removeDrawing } from '@/uni_modules/nex-kline'
export default {
data() { return { engineId: 0, revision: 0, mode: 'none', selectedId: -1, savedJson: '' } },
methods: {
// drawMode='trendline' 时 tap 两次落两锚点 → 自动画线 → 回带含 id 的画线 JSON
onAdd(e: string) { const d = JSON.parse(e); /* d.id / d.kind / d.anchors,存盘 */ },
// drawMode='none' 时 tap 命中已有画线 → 选中(可拖锚点编辑)
(e: string) { this.selectedId = JSON.parse(e).id },
// 拖锚点编辑后 → 更新后画线 JSON(据此存盘)
onChange(e: string) { /* 覆盖存盘该 id */ },
delSelected() { removeDrawing(this.engineId, this.selectedId); this.selectedId = -1; this.revision++ },
// 跨会话保存/恢复画线
save() { this.savedJson = exportDrawings(this.engineId) },
restore() { importDrawings(this.engineId, this.savedJson); this.revision++ }
}
}
</script>
画线锚点存绝对 (ts,price),切复权/切周期不漂移。画线主用 candle 模式(分时/深度模式画线的纵向命中是 v2.0 已知边界,见「限制」)。
API 模式(29 引擎 API)
import {
// 基础 14(v1)
createKlineEngine, loadCandlesFlat, loadCandlesJson, appendCandle, updateLastCandle,
setPeriod, setIndicators, setTheme, setViewport, renderFrame, getCrosshairData,
getMeta, destroyEngine, klineVersion,
// 画线 8(v2)
addDrawing, updateDrawing, removeDrawing, clearDrawings, listDrawings, exportDrawings, importDrawings, hitTestAt,
// 形态/昨收/复权/深度/联动 7(v2)
setChartMode, setPrevClose, setAdjustMode, setAdjustFactors, setDepthData, setCrosshairAt, setViewportByTime
} from '@/uni_modules/nex-kline'
const id = createKlineEngine('{}') // 建引擎返 engineId
loadCandlesFlat(id, [/* [ts,o,h,l,c,v]×N 扁平 */]) // 高速装载(事务化)
setPeriod(id, '5m') // 周期聚合
setIndicators(id, '{"ma":[5,10,20],"subs":["macd","kdj"]}') // v2:subs 数组多副图
setViewport(id, 0, 120) // 视口(起始 index + 可见根数)
// v2 画线(程序化):
const drawId = addDrawing(id, '{"kind":"trendline","anchors":[{"ts":0,"price":100},{"ts":60000,"price":104}]}')
// v2 分时 / 复权 / 深度 / 联动:
setChartMode(id, 'timeshare'); setPrevClose(id, 100) // 分时 + 昨收基准
setAdjustFactors(id, '[{"ts":60000,"factor":0.9}]'); setAdjustMode(id, 'forward') // 前复权
setDepthData(id, '{"bids":[[99.9,10]],"asks":[[100.1,15]]}'); setChartMode(id, 'depth') // 深度
const meta = getMeta(id) // {candleCount, viewport, chartMode, viewportStartTs, ...}
const cross = getCrosshairData(id, 100) // 十字线数据(形态按 mode 分派,须先 renderFrame)
destroyEngine(id) // 用完释放(防注册表泄漏)
renderFrame(id, w, h, dpr)返回 RGBA 帧字节——热环路由原生视图内部调用,业务层一般不用(用<nex-kline>组件即可)。自绘场景才手动取字节。
多图多周期联动(v2)
两个 <nex-kline> 实例监听彼此事件互调 setter(联动策略在 JS,引擎不做跨实例广播):
// 图 A 十字线动 → 驱动图 B 十字线到同一时间(跨周期天然对齐)
onCrosshairA(e: string) { setCrosshairAt(engineB, JSON.parse(e).ts) }
// 图 A 视口变 → 图 B 视口对齐同一时间段(各自周期桶区间)
onViewportA(e: string) { const m = JSON.parse(e); setViewportByTime(engineB, m.viewportStartTs, m.viewportEndTs) }
H5 注意事项
// #ifdef H5
import { ensureReady } from '@/uni_modules/nex-kline'
await ensureReady() / 异步初始化,构造引擎前等一次
// #endif
H5 端 <nex-kline> 用 canvas putImageData 帧循环渲染,手势(平移/双指缩放/单击十字线)在浏览器端处理。价/时间轴标签是纯数字,无需额外字体(内核内嵌 NotoSans)。
蜡烛数据与指标
- 扁平六元组
[ts, o, h, l, c, v]:ts毫秒(严格递增),OHLC 须满足h ≥ max(o,c)、l ≤ min(o,c);非法数据整批拒绝(事务化)。 - JSON 入口:
loadCandlesJson接受[{ts,open|o,high|h,low|l,close|c,volume|v}](短键别名,volume 可缺省)。 - 实时 tick:
appendCandle(新一根,ts > last)/updateLastCandle(改写最后一根,ts == last),配合revision++驱动组件重渲。 - 指标 DSL(v2 扩展):
{"ma":[5,10,20],"ema":[12],"boll":[20,2],"sar":[0.02,0.2],"subs":["macd","kdj","rsi"],"macd":[12,26,9],"kdj":9,"rsi":14,"wr":14,"cci":20}——ma/ema窗口数组、boll为[n,k]数组、macd为[fast,slow,signal]数组、kdj/rsi/wr/cci为单个数字(窗口)、sar为[step,max](主图叠加);subs数组(最多 3 个副图名,sub单值仍兼容 v1);窗口参数 ∈ [1,500],越界报错。 - 画线 JSON:
{"kind":"trendline"|"horizontal"|"ray"|"rect"|"fib","anchors":[{"ts":..,"price":..},…]}(trendline/ray/rect/fib 两锚点、horizontal 一锚点),可选"color":"#RRGGBB"/"snapToCandle":bool;锚点是绝对 (ts,price) 数据坐标。 - 复权 / 深度 / 联动:
setAdjustFactors('[{"ts":..,"factor":..}]')(factor>0、按 ts 升序);setDepthData('{"bids":[[price,qty],…],"asks":[…]}')(各 ≤500 档);setCrosshairAt(ts)(负 ts 清除)/setViewportByTime(startTs,endTs)。
限制与防护(内核硬校验,超限报错不静默截断)
- 单引擎蜡烛数 ≤ 100 万根;指标窗口 ∈ [1,500];副图 ≤ 3;深度档 ≤ 500
- 画布 逻辑×dpr ≤ 4096;dpr ∈ [1,4]
- 网络拉数据 / 后端对接 / 图表动画 / log 轴:不承诺(
@loadmore只上抛边界事件,加载历史由使用方自理) - v2.0 已知边界(记 v2.1):① 分时模式十字线
py与画线纵向命中按蜡烛几何反推(横向 index/ts/OHLC 全对、纵向像素偏——画线主用 candle 模式);② 组件画线编辑无可视锚点手柄点,拖锚点价 snap 蜡烛收盘(无自由改价);③ 同类型多副图 crosshair 字段名会撞(建议 subs 元素类型不重复);④ SAR 为简化变体,与 TA-Lib 不逐字一致(趋势方向/转向时机一致);⑤ 复权只 OHLC 价、量不变
常见问题
- Android 标准基座报"找不到 jna":原生插件须自定义基座(插件依赖 原生运行依赖,标准基座不含)。制作自定义基座后即可正常运行。
- 组件不刷新:改数据(append/updateLast/setPeriod/setIndicators/setTheme)后记得自增
revisionprop——组件按revision变更重渲,不主动轮询引擎。 - 十字线报错"未渲染":
getCrosshairData须在至少渲染过一帧后调用(组件已自动处理;自绘时先renderFrame再取十字线)。 - iOS 显示异常 / 手势不跟手:iOS 原生视图转译为全仓 gated 项(cli
--compile空挂),CGImage 字节序 / 手势 recognizer 形态待离线基座/真机微调;H5 与 Android 已验证。
平台说明
| 端 | 实现 | 说明 |
|---|---|---|
| Android | 原生扩展库(arm64-v8a / armeabi-v7a / x86_64)+ 原生绑定层 Kotlin 绑定 + 原生 View 视图 |
需自定义基座(云打包);手势热环路零桥接开销 |
| iOS | 原生扩展库(device + simulator)+ 原生绑定层 Swift 绑定 + 原生 UIView 视图 |
宿主工程需开启"支持 Swift";转译 gated(v2 含 drawMode 分支随家族 iOS 迁移轮验证;绑定层 swiftc 已验) |
| H5 | 同一自研原生内核编译 H5 端引擎(base64 内嵌,免静态资源配置)+ canvas putImageData | 首次调用前 await ensureReady() |
技术支持 / 问题反馈:插件评论区或仓库 issue。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 1178
赞赏 0
下载 12438998
赞赏 1934
赞赏
京公网安备:11010802035340号