HarmonyOS 股票 K 线图完整源码与金融图表模板

实例:股票 K 线图(K-Line Chart)|技术:全量代码解读、操作剧本、金融图表模式抽象

一、本篇定位

前两篇分别讲了绘制层与交互层,本篇完成三件事:

  1. 全量源码逐段解读------KLineChartPage 从头到尾过一遍;
  2. 运行效果演示------从触摸查看 OHLC 到换数据的完整操作;
  3. 模式抽象------"金融图表"通用模板,附两个改写场景。

二、完整源码:KLineChartPage.ets

typescript 复制代码
/**
 * 股票 K 线图 ------ 自定义 Canvas(CanvasRenderingContext2D)应用 8
 * 对应博客:Canvas_2d/8_股票K线图/8-1 ~ 8-3
 *
 * 功能:
 *  1. 蜡烛图:K 线(开/高/低/收)绘制,涨红跌绿
 *  2. 均线:MA5 / MA10 / MA20 三条折线
 *  3. 十字光标:触摸显示对应 K 线的 OHLC 数据
 *  4. 数据生成:模拟随机游走生成 K 线数据
 */
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG = 'KLineChart';

/** K 线数据 */
interface KLine {
  open: number;
  high: number;
  low: number;
  close: number;
}

@Entry
@Component
struct KLineChartPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private canvasW: number = 0;
  private canvasH: number = 0;

  private data: KLine[] = [];
  private maxPrice: number = 0;
  private minPrice: number = 0;
  private candleW: number = 8;
  private gap: number = 4;
  private padL: number = 44;
  private padR: number = 12;
  private padT: number = 16;
  private padB: number = 8;

  @State touchIndex: number = -1;
  @State infoText: string = '触摸图表查看 OHLC 数据';

  aboutToAppear(): void {
    this.generateData();
  }
  // generateData / priceToY / indexToX / redraw / drawGrid
  // drawCandles / drawMAs / drawMA / drawCrosshair / onTouchChart / build
  // (见上两篇逐段解读)
}

逐段解读总表

代码段 职责 关键决策
KLine 接口 OHLC 四价 蜡烛数据模型
布局常量 candleW/gap/pad* 图表几何参数
generateData 随机游走 60 根 模拟行情
priceToY 价格→像素 Y 归一化+翻转+平移
indexToX 索引→像素 X 线性排布
redraw 分层重绘 层级顺序
drawGrid 网格 + 价格标签 刻度可读
drawCandles 蜡烛绘制 影线+实体
drawMA 均线滑动平均 三线复用
drawCrosshair 光标 + 浮层 交互反馈
onTouchChart 命中检测 坐标反算

三、接入工程三步

Step 1:放文件

  • KLineChartPage.etsentry/src/main/ets/pages/canvas_2d/

Step 2:注册路由(main_pages.json)

json 复制代码
"pages/canvas_2d/KLineChartPage",

Step 3:首页入口(Index.ets)

typescript 复制代码
Button('📈 36 股票 K 线图')
  .fontSize(14)
  .width('80%')
  .onClick(() => {
    this.getUIContext().getRouter().pushUrl({ url: 'pages/canvas_2d/KLineChartPage' });
  })

四、运行效果演示(操作剧本)

场景一:首次打开

步骤 界面表现 数据来源
1 标题栏:"📈 股票 K 线图",提示"触摸图表查看 OHLC 数据" ---
2 画布:白底,浅灰网格 5 等分,左侧价格标签(约 88~112 元),60 根红绿蜡烛 generateData + drawCandles
3 蜡烛上方三条均线:蓝 MA5 / 橙 MA10 / 紫 MA20 平滑蜿蜒 drawMA
4 图例:"━MA5 ━MA10 ━MA20 红涨 绿跌" ---

场景二:触摸查看 OHLC

  1. 触摸画布中部 → 十字光标虚线出现在最近的 K 线位置;
  2. 左上角深色浮层显示:开/收/高/低/涨跌 + 右侧红绿涨跌色条;
  3. 标题栏同步显示"第 32 根 · 开 98.5 收 101.2 高 102.0 低 97.8";
  4. 触摸另一处 → 光标移动、数据更新。

场景三:涨跌观察

触摸红色蜡烛(涨)→ 浮层涨跌色条红、涨跌 +2.7;触摸绿色蜡烛(跌)→ 色条绿、涨跌 -1.3。颜色与数值双重确认涨跌

场景四:换数据

点"换数据"→ 生成新随机行情,光标消失、提示重置。连点几次看不同"行情"(有的上涨趋势、有的震荡)。

五、模式抽象:金融图表通用模板

5.1 模板骨架

复制代码
┌─────────────────────────────────────────────┐
│  数据层                                     │
│  KLine 数组(OHLC) / 价格范围 min~max       │
└──────────────────┬──────────────────────────┘
                   │
┌──────────────────▼──────────────────────────┐
│  坐标变换层                                 │
│  valueToY:归一化 → 翻转 → 平移             │
│  indexToX:索引 × 占宽 + 偏移               │
│  (逆运算做命中检测)                        │
└──────────────────┬──────────────────────────┘
                   │
┌──────────────────▼──────────────────────────┐
│  绘制层                                     │
│  网格 → 蜡烛/柱 → 指标线 → 光标             │
│  (分层顺序 = 视觉层级)                     │
└──────────────────┬──────────────────────────┘
                   │
┌──────────────────▼──────────────────────────┐
│  交互层                                     │
│  触摸 → 坐标反算 → 命中 → 光标 + 浮层        │
└─────────────────────────────────────────────┘

5.2 六个约定

  1. 数据与绘制解耦:KLine 数组只管数据,绘制只读它;
  2. 坐标变换成对:valueToY 与 yToValue、indexToX 与 xToIndex 互为逆运算;
  3. 归一化是核心:任何数据域 → 0,1 → 像素域;
  4. 绘制分层:网格垫底、数据中、交互浮层最上;
  5. 状态复位:setLineDash 用完复位、换数据清交互状态;
  6. 参数配置化:candleW/gap/pad 是常量,调参改观感。

5.3 两个改写场景

场景 A:分时图

K 线实例 分时改写
KLine 数组 时间点数组(time, price)
蜡烛绘制 折线绘制(当日价格 + 均价线)
均线 均价线(成交量加权)
Y 轴 昨收价为中心 ± 百分比

场景 B:MACD 指标图

K 线实例 MACD 改写
主图蜡烛 保留(K 线 + 均线)
副图 DIF/DEA 折线 + MACD 柱(红正绿负)
布局 双绘图区(价格区 + 指标区)

场景 C:柱状成交量图------K 线下方成交量柱(红涨绿跌同色),模板复用。

三个场景的共同点:"数据 → 坐标变换 → 分层绘制 → 交互命中"四层结构。掌握 36,任何金融图表(K 线、分时、指标)都能搭建。

六、三篇内容总对照

篇章 核心知识点 一句话总结
36-1 坐标变换与蜡烛图绘制 归一化映射、蜡烛、均线 数据域↔像素域映射
36-2 十字光标与触摸交互 命中检测、虚线、浮层 坐标往返变换
36-3 完整代码与运行效果 全量源码、操作剧本、金融模板 四层结构,改数据即新图

七、FAQ(三篇汇总补遗)

Q1:36 和 23 数据图表有什么区别?

A:23 是基础图表(柱/折线/饼,静态 + 简单动画);36 是金融图表(蜡烛 + 均线 + 十字光标交互)。36 把坐标变换和触摸命中提升为第一公民------这是专业图表的门槛。

Q2:价格范围为什么用 high 最大 / low 最小?

A:Y 轴要覆盖全部价格波动(影线顶端到低端)。若用开收范围,影线会超出绘图区。范围 = 数据的极值域

Q3:均线计算 O(n²) 会卡吗?

A:60 根 × MA20 = 1200 次加法,毫秒级。数据上万时可滑动增量(sum += new - old)降为 O(n)。教学直算,大数据优化

Q4:命中检测为什么用 round 而不用 floor?

A:round 就近取整------触摸在两个 K 线中间时选"较近"的一根,更符合直觉。floor 会永远选左侧,边缘处有偏差。

Q5:真机触摸的 t.x 是相对什么?

A:TouchEvent.touches0.x/y 是相对组件 的坐标(组件内左上角为原点),所以直接用于 indexToX 逆运算(减去 padL)。组件相对坐标正好匹配画布坐标系。

Q6:能加多周期切换(日K/周K)吗?

A:能------数据源按周期聚合(日线数据 → 周线聚合),绘制层不变。周期是数据预处理,不是绘制问题

八、结语

三篇文章完整走完了 K 线图的"绘制 → 交互 → 复用"闭环:

  • 1 教你坐标变换:归一化映射、蜡烛绘制、均线计算;
  • 2 教你触摸交互:命中检测、十字光标、数据浮层;
  • 3 教你模式复用:四层结构模板,改数据即覆盖分时、MACD、成交量。

K 线图是 Canvas 系列"数据可视化"的最高峰------它把数据图表的基础能力升级为专业金融图表,坐标变换 + 交互命中的组合是数据可视化的通用钥匙。

相关推荐
210Brian2 小时前
STM32学习笔记(七)TIM定时中断(上)
笔记·stm32·学习
大雷神2 小时前
HarmonyOS 真机实战:一张普通照片怎样自动抠出人物并生成旅行海报
harmonyos
yuhulkjv3352 小时前
告别“复制-粘贴-崩格式”:ChatGPT鸿蒙版导出word格式的底层技术重构
ai·chatgpt·word·harmonyos·ai导出鸭
海兰3 小时前
【Kafka学习2】Apache Kafka 典型应用场景
学习·kafka·apache
YM52e3 小时前
ArkTS 2048 手感调优:棋盘渲染与滑动交互
华为·harmonyos
边境悍匪3 小时前
蜗牛学苑 Java 学习 Day23|SpringBoot 思维导图复盘
学习
晴天163 小时前
HarmonyOS 和 React 对比-Day22
前端·华为·harmonyos
xx~t3 小时前
嵌入式学习22
数据结构·学习·算法·排序算法
砚凝霜3 小时前
软考网络工程师|案例分析:华为全套综合实验核心知识点 & 考点总结
网络·华为