绘制K线第一章:可见区间处理

绘制K线第一章:可见区间处理

概述

在入门版本中,我们绘制了所有K线数据。但当数据量很大时,所有K线会挤在一起或超出屏幕,无法正常显示。

可见区间处理就是解决这个问题:只绘制屏幕能容纳的K线数量,让图表清晰可读。

为什么需要可见区间

问题场景

假设有以下情况:

  • 屏幕宽度:1080px
  • 每根K线占用:30px(20px宽度 + 10px间距)
  • 可显示的K线数量:1080 ÷ 30 = 36根
  • 实际数据:1000根K线

如果绘制所有1000根K线:

  • K线会挤在一起,无法看清
  • 或者超出屏幕,看不到完整内容

解决方案

只显示最后36根K线(最新的数据),这样:

  • K线清晰可读
  • 不会超出屏幕

实现原理

核心逻辑

scss 复制代码
// 1. 计算可见K线数量
val totalCandleWidth = config.getTotalCandleWidth()  // 30px
val visibleCount = (width / totalCandleWidth).toInt()  // 1080 ÷ 30 = 36

// 2. 获取可见数据(只取最后N根)
val visibleData = if (klineData.size > visibleCount) {
    klineData.takeLast(visibleCount)  // 取最后36根
} else {
    klineData  // 数据不足,全部显示
}

// 3. 只对可见数据计算价格范围
val priceRange = calculatePriceRange(visibleData)

// 4. 只绘制可见数据
visibleData.forEachIndexed { index, entity ->
    drawCandle(...)
}

关键点

  1. 计算可见数量屏幕宽度 ÷ 每根K线占用宽度
  2. 取最后N根 :使用 takeLast() 方法,显示最新的数据
  3. 价格范围计算:只基于可见数据计算,确保Y轴比例正确

代码实现(KLineViewCase2)

类图

kotlin 复制代码
@startuml
class KLineViewCase2 {
  - klineData: List<KLineEntity>
  - config: KLineConfig
  + setKLineData(data: List<KLineEntity>)
  - calculatePriceRange(data: List<KLineEntity>): Pair<Float, Float>
}

KLineViewCase2 --> KLineConfig : 依赖
KLineViewCase2 --> KLineEntity : 使用

note right of KLineViewCase2
  相比Case1,增加了可见区间处理:
  1. 计算可见K线数量
  2. 只取最后N根数据
  3. 只对可见数据计算价格范围
end note

@enduml

核心代码(可见区间部分)

onDraw() 方法中,相比Case1增加了可见区间处理:

scss 复制代码
// 1. 计算可见区间:根据屏幕宽度计算能显示多少根K线
val totalCandleWidth = config.getTotalCandleWidth()
val visibleCount = (width / totalCandleWidth).toInt()

// 2. 获取可见的K线数据(只显示最后N根,最新的数据)
val visibleData = if (klineData.size > visibleCount) {
    klineData.takeLast(visibleCount)  // 取最后N根
} else {
    klineData  // 数据不足,全部显示
}

// 3. 计算可见数据的价格范围(注意:传入visibleData而不是klineData)
val priceRange = calculatePriceRange(visibleData)

// 4. 绘制可见的K线(使用visibleData)
visibleData.forEachIndexed { index, entity ->
    drawCandle(canvas, entity, index, minPrice, maxPrice, height)
}

关键改动

  • calculatePriceRange() 方法现在接受 data 参数,可以传入可见数据
  • 其他绘制逻辑与Case1相同(参考入门文档)

与Case1的对比

特性 Case1(入门版) Case2(可见区间版)
绘制数据 所有数据 只绘制可见数据(最后N根)
价格范围计算 基于所有数据 基于可见数据
适用场景 数据量小(< 50根) 数据量大(> 50根)
代码复杂度 简单 稍复杂(增加可见区间逻辑)

完整绘制链路

相比Case1,Case2在绘制链路中增加了可见区间处理:

scss 复制代码
1. 设置K线数据 → 触发onDraw()重绘
   ↓
2. onDraw()方法执行:
   ├─ 绘制背景(与Case1相同)
   ├─ 检查数据是否为空(与Case1相同)
   ├─ 【新增】计算可见区间
   │   ├─ 计算可见K线数量(屏幕宽度 ÷ 每根K线宽度)
   │   └─ 获取可见数据(取最后N根)
   ├─ 计算价格范围(基于可见数据,不是所有数据)
   └─ 遍历可见K线数据并绘制(绘制逻辑与Case1相同)

说明:绘制K线的具体步骤(计算坐标、绘制影线、绘制实体)与Case1相同,参考入门文档。

关键概念

可见K线数量计算

scss 复制代码
可显示的K线数量 = 屏幕宽度 ÷ 每根K线占用的总宽度
                = width ÷ (candleWidth + candleSpacing)
                = width ÷ totalCandleWidth

示例

  • 屏幕宽度:1080px
  • 每根K线占用:30px(20px宽度 + 10px间距)
  • 可见数量:1080 ÷ 30 = 36根

取最后N根数据

arduino 复制代码
val visibleData = if (klineData.size > visibleCount) {
    klineData.takeLast(visibleCount)  // 取最后N根(最新数据)
} else {
    klineData  // 数据不足,全部显示
}

说明

  • 如果数据量 > 可见数量:只取最后N根(显示最新数据)
  • 如果数据量 ≤ 可见数量:全部显示

价格范围只基于可见数据

这是关键点:价格范围必须只基于可见数据计算,而不是所有数据。

为什么?

  • 如果基于所有数据计算价格范围,可见数据的价格变化可能很小
  • 导致Y轴比例不合适,K线看起来像一条线
  • 只基于可见数据计算,Y轴比例正确,K线清晰可见

注意事项

  1. 数据顺序 :确保数据是按时间顺序排列的(从旧到新),这样 takeLast() 才能取到最新数据
  2. 边界情况:当数据量小于可见数量时,需要全部显示
  3. 价格范围:必须只基于可见数据计算,不能基于所有数据

总结

可见区间处理是K线绘制的重要优化:

  • 解决数据量大时的显示问题
  • 只绘制屏幕能容纳的K线
  • 价格范围只基于可见数据计算
  • 为后续的滚动、缩放功能打下基础

效果

相关推荐
头发还在的女程序员8 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats8 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
我命由我123459 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
都叫我大帅哥11 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.12 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
腻害兔13 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:IM 即时通讯模块,一个被低估的「全功能聊天系统」
java·前端·vue.js·产品经理·ai编程
心念枕惊13 小时前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
景同学15 小时前
把 AI 用到线上运维:可行、有效,前提是喂足信息——一次 Full GC 排障实录
java·人工智能·后端
C++、Java和Python的菜鸟15 小时前
第7章 后端Web实战(Tlias系统)
java
憧憬成为java架构高手的小白16 小时前
黑马八股--spring框架学习
java·学习·spring