首页/新闻资讯/正文详情

使用 @antv/f2-algorithm 为 F2 移动端图表做高性能数据采样

发布时间:2026/9/26 10:11:31 来源:云帆数科 栏目:资讯中心
使用 @antv/f2-algorithm 为 F2 移动端图表做高性能数据采样
数据可视化前端【免费下载链接】F2An elegant, interactive and flexible charting library for mobile.项目地址https://gitcode.com/gh_mirrors/f2/F2点击查看免费下载数据采样down sampling / data sampling是移动端图表面对大数据量时的常用优化手段在不破坏曲线整体趋势的前提下用更少的点完成渲染从而降低内存占用、缩短首帧绘制时间。antv/f2-algorithm是 F2 官方配套的算法扩展包提供基于LTTBLargest-Triangle-Three-Buckets最大三角形三桶与最近邻 / 最大 / 最小nearest / max / min等策略的降采样函数。阅读本文后你将掌握lttbDownSample与rateDownSample的完整 API、参数语义与源码级原理并能在 F2 图表如折线图中直接落地数据采样兼顾趋势保真与渲染性能。一、什么是 f2-algorithm定位与适用场景antv/f2-algorithm是 F2 仓库中与主包平行的独立算法包版本号与主库保持同步当前仓库内为 5.7.0主包antv/f2为 5.14.0。它的定位在 packages/f2-algorithm/README.md 中写得非常直白F2 的算法库 / 常用算法扩展包即把移动端图表中最常用、与业务解耦的通用算法从主包中抽离出来按需引入、按需打包。典型适用场景包括服务端只吐全量明细数据、前端负责瘦身的移动端 K 线、走势、监控类图表每秒一条数据、动辄上万点的时序曲线例如日内行情、实时指标需要在图表层保留尖峰 / 低谷语义而非简单等间隔抽点的场景。需要说明的是抽样并不能替代聚合若业务只关心统计口径如日均值更合适的做法仍是服务端聚合或前端分页。抽样解决的是趋势可读 渲染不卡的工程问题正如 site/docs/tutorial/data.zh.md 中大数据量处理一节所强调的前端抽样与分页、服务端聚合是并列的三条建议路径。从源码结构看该包只包含三个源文件入口统一从 packages/f2-algorithm/src/index.ts 导出两个纯函数import lttbDownSample from ./lttbDownSample; import rateDownSample from ./rateDownSample; export { lttbDownSample, rateDownSample };也就是说该包的所有能力都可以概括为两个函数lttbDownSample趋势保真型采样与rateDownSample常见统计型采样。二、快速上手把采样结果喂给 Chart原 README 给出的用法是将采样函数直接作为默认导出的dataSample使用。与之等价、且当前源码实际导出的写法是具名导入两个函数。最直接的做法是配合antv/f2的 JSX 声明式 API 使用import { Canvas, Chart, Line } from antv/f2; import { lttbDownSample } from antv/f2-algorithm; const data [/* 上万条 { date, value } 记录 */]; const sampleData lttbDownSample(data, { rate: 7, // 每 7 条保留约 1 条 dimension: value, // 以哪个字段作为 y 值参与面积计算 }); Canvas pixelRatio{1} Chart data{sampleData} Line xdate yvalue / /Chart /Canvas;采样发生在数据进入Chart之前因此 F2 主库完全无感知它拿到的就是一份已经瘦身的普通数据数组。这也意味着你可以把采样函数用在任何图表类型上折线、面积、K 线等并在采样前统一做Number()类型收敛——例如测试中常见的value: Number(d.value)转换因为 LTTB 内部会做数值运算字符串类型的数值会被Number()隐式转换。包内自带一套基于真实线上数据的可视化回归测试见 packages/f2-algorithm/test/sample.test.tsx它从固定 URL 拉取时序数据分别渲染原数据、lttbrate: 7、nearestrate: 7三张图并与基线快照比对同时覆盖了rate大于数据条数时 LTTB 的降级行为。这套测试既验证了算法输出不会破坏图表渲染也给出了采样后直接渲染的标准范例。三、rateDownSamplenearest / max / min 统计采样3.1 函数签名与默认值定义于 packages/f2-algorithm/src/rateDownSample.tsexport interface OptionsProps { sampling: nearest | max | min | Function; // 采样策略 rate: number; // 周期每 rate 条数据抽 1 条 dimension: string; // 参与比较的数值字段名默认 value } export default function rateDownSample(data, options?: OptionsProps);参数说明参数类型默认值说明data对象数组必传原始数据每一项需包含dimension指定的字段samplingnearest \| max \| min \| Functionnearest每个采样窗口内取哪一条作为代表ratenumber5抽点周期如7表示每 7 条取 1 条最终点数约为data.length / ratedimensionstringvalue用于max/min比较的数值字段名3.2 三种内置策略的语义nearest直接取每个窗口的第一条记录frame[0]。它是最省计算的抽稀结果点数严格等于Math.ceil(len / rate)但遇到周期抖动时可能产生视觉上的跳变。max/min在每个窗口内遍历取dimension字段值最大 / 最小的那条记录。这对保留极值尖峰非常有效——金融行情、监控告警类图表最关心的高低点不会被均匀抽稀抹掉。自定义函数sampling也可以是函数。它会收到两个参数(frame, dimension)——frame是当前窗口内的数据子数组dimension是选项里传入的字段名返回值即为该窗口的代表点。这允许你自由实现中位数、均值、首末点等任意策略源码注释中已留有TODO 中位数 median的扩展位。3.3 执行流程与边界条件rateDownSample的执行分三步参数校验只有当isFinite(rate) rate 1时才执行采样否则原样返回data——保证调用方传入非法 rate 时不会得到空数组或崩溃。选择 samplersampling是字符串则从内置samplers表取函数是函数则直接使用。分窗抽取按frameSize Math.floor(rate)把数据切成等长窗口最后一个窗口不足长时截断对每个窗口调用 sampler 取代表点顺序拼装成新的数组返回。// 核心分窗逻辑源码简化示意 function downSample(data, rate, sampler, dimension) { const sampled []; let frameSize Math.floor(rate); for (let i 0; i len; i frameSize) { frameSize frameSize len - i ? len - i : frameSize; // 末窗截断 const frameValues data.slice(i, i frameSize); sampled.push(sampler(frameValues, dimension)); } return sampled; }需要注意窗口起点固定为0, frameSize, 2*frameSize, ...与数据本身的相位无关nearest在相位上会系统性偏向窗口首点。若你的曲线带有固定周期如整点数据这种固定相位抽稀可能放大周期采样误差此时应改用趋势保真型 LTTB。四、lttbDownSample最大三角形三桶算法4.1 为什么需要 LTTBnearest等统计采样把数据切在固定的等宽窗口上代价是窗口内的曲线形状信息尤其是尖峰可能被丢弃且抽点位置与数据相位强相关。LTTB 则换了一种思路——保留视觉重要性最大的点让折线在点数大幅下降后仍保持原始的形状感知。其核心思想可用源码头部的示意图概括* A B C * * 桶包含数据子区间的有序集。算法把数据点按序装入若干桶bucket对每个桶内的候选点以上一个已选点 A 与下一个桶均值点 C 连成的基线为底计算该候选点构成的三角形面积面积最大者即为视觉贡献最大的点选入结果并成为下一轮的 A。本质上这是一个贪心的形状保真过程。4.2 函数签名与默认值定义于 packages/f2-algorithm/src/lttbDownSample.tsexport interface OptionsProps { rate: number; // 周期默认 5 dimension: string; // 数值字段名默认 value } export default function lttbDownSample(data, options?: OptionsProps);与rateDownSample的差异在于LTTB 不提供采样策略参数只有一个dimension参与三角形面积计算目标点数由targetCount data.length / rate决定。4.3 算法步骤拆解结合源码逐段解释确定目标点数并降级targetCount len / rate。若rate len或targetCount 2直接返回原数据——点数太少时三角形算法失去意义。这正是 CHANGELOG 中 #1880 data数量小于rate 修复的边界场景数据量小于 rate 时不再产出异常结果。计算桶宽bucketSize floor((len - 2) / (targetCount - 2))。首尾两点第一个点 A 与最后一个点被无条件保留中间需要挑选targetCount - 2个点因此桶宽由剩余点数 / 剩余需选点数决定。固定 A 点a 0即原始数据的第一个点无条件进入结果集。逐桶迭代对第 i 个桶先算出C 桶的均值点(avgX, avgY)C 桶范围是[i bucketSize, i 2*bucketSize)对其内所有点的dimension值求平均得到avgY桶中点作为avgX然后在B 桶[i, i bucketSize)内遍历每个候选点(rangeOffs, y)计算它与 A 点、C 均值点构成的三角形面积area 0.5 * |(pointA_x - avgX) * (y - pointA_y) - (pointA_x - rangeOffs) * (avgY - pointA_y)|面积最大的候选点maxAreaPoint被收入结果集并成为下一轮的 A 点a nextA。收尾循环结束后把最后一个点data[len - 1]加入结果集返回。// 源码核心循环结构示意 sampled[0] data[0]; for (let i 1; i len - 1; i bucketSize) { // 计算 C 桶均值 const avgX (avgRangeEnd avgRangeStart) / 2; let avgY 0; for (; avgRangeStart avgRangeEnd; avgRangeStart) { avgY Number(data[avgRangeStart][dimension]); } avgY / avgLength; // 在 B 桶内找面积最大的点 let maxArea -1, maxAreaPoint, nextA; for (let rangeOffs i; rangeOffs rangeTo; rangeOffs) { const area 0.5 * Math.abs( (pointA_x - avgX) * (Number(data[rangeOffs][dimension]) - pointA_y) - (pointA_x - rangeOffs) * (avgY - pointA_y) ); if (area maxArea) { maxArea area; maxAreaPoint data[rangeOffs]; nextA rangeOffs; } } sampled.push(maxAreaPoint); a nextA; } sampled.push(data[len - 1]);4.4 LTTB 的工程性质首尾必保第一个点和最后一个点无条件保留曲线不会因抽样而缩短。形状优先在总点数固定的前提下LTTB 会把预算花在拐点、尖峰这些视觉关键位置因此降采样后的曲线与原始曲线在外观上高度一致——这正是 4.1 节图中 LTTB 结果比nearest保留更多局部波动细节的原因。有状态迭代每一轮选择依赖上一轮选中的 A 点因此结果与数据顺序强相关对乱序数据应先按 x 排序再采样。复杂度适中每次迭代只扫描当前桶整体为 O(n)适合在移动端主线程内直接执行。五、原 README 用法勘误与正确引入方式原 README 中的示例使用了import dataSample from antv/f2-algorithm这种默认导入写法并把sampling: nearest与rate: 7直接传给该函数。但从当前仓库源码看packages/f2-algorithm/src/index.ts 只导出了lttbDownSample与rateDownSample两个具名函数并不存在默认导出。因此推荐按如下方式书写import { rateDownSample } from antv/f2-algorithm; // 统计采样 import { lttbDownSample } from antv/f2-algorithm; // 趋势保真采样 // 最近邻采样每 7 条保留 1 条 const sampleData rateDownSample(data, { sampling: nearest, rate: 7, dimension: value, }); // 或 LTTB 趋势保真采样 const sampleData lttbDownSample(data, { rate: 7, dimension: value, });两个函数的入参都遵循缺省可用原则rate默认5dimension默认value。如果你的数据字段名不是value务必显式传入dimension否则 LTTB 的面积计算与max/min比较都会落在错误的字段上。六、性能权衡与选型建议需求推荐函数理由只想快速减少点数、不关心波形细节rateDownSamplenearest计算最轻结果确定需要保留极值尖峰行情、告警rateDownSamplemax/min窗口内极值不丢失点数大幅下降后仍要保持曲线形状lttbDownSample三角形面积贪心保形首尾必保业务语义复杂均值 / 中位数等rateDownSample 自定义函数sampling支持任意(frame, dimension) point函数工程上再补充三条实践建议先转数值再采样dimension字段建议统一Number()收敛避免字符串参与面积 / 比较运算时的隐式转换开销与精度隐患。rate 选择以目标点数 ≈ 屏幕像素宽度的 1~2 倍为经验基准。移动端 375pt 宽的图表rate取 5~10 通常已足够rate过大目标点数过少会丢失可读性rate过小则失去采样意义。按 x 排序后使用 LTTBLTTB 是有状态贪心算法乱序输入会扭曲三角形基线请确保 x 维度单调递增。七、测试与可视化回归验证f2-algorithm 的测试 直接验证了本文的核心结论可作为验收采样质量的标准流程原数据基线直接渲染原始上万条数据产出基线快照作为后续对照LTTB 采样lttbDownSample(data, { rate: 7, dimension: value })后渲染对比快照确认曲线形态保持一致nearest 采样rateDownSample(data, { sampling: nearest, rate: 7, dimension: value })后渲染确认点数下降但整体走势不变边界用例构造只有 9 条数据、rate: 7的输入验证 LTTB 在数据量小于 rate时不崩溃并给出合理结果。这些快照均存放在 packages/f2-algorithm/test/image_snapshots/ 下可以直接对比三种策略在同一批数据上的实际渲染差异LTTB 在相同点数预算下保留了最多的局部波动细节nearest输出最简洁原始数据则细节最全但渲染成本最高。测试还引用了jest-mock-random依赖见 packages/f2-algorithm/package.json表明官方在 CI 中稳定复现随机性保证快照可重复比对。八、总结antv/f2-algorithm用两个纯函数覆盖了移动端图表最主要的两种降采样诉求rateDownSample提供 nearest / max / min / 自定义四类统计采样胜在简单与确定lttbDownSample通过最大三角形三桶贪心算法在点数预算内最大化保留曲线形状。两者都内置了非法参数降级数据量不足时原样返回且作为独立包按需引入不会给主包增加负担。对 F2 图表而言把采样放在Chart data{...}之前是最干净、最可测试的接入方式——采样逻辑与渲染完全解耦这正是该包常用算法扩展定位的工程价值所在。赞分享数据可视化前端【免费下载链接】F2An elegant, interactive and flexible charting library for mobile.项目地址https://gitcode.com/gh_mirrors/f2/F2点击查看免费下载相关推荐探索未来数据可视化AntV F2一款强大的移动端图表库探索未来数据可视化AntV F2一款强大的移动端图表库 在数据爆炸的时代有效的数据可视化工具成为了理解复杂信息的关键。 就是这样一款专为移动端设计的高性能数据可视化前端在React项目中优雅使用AntV F2图表库在React项目中优雅使用AntV F2图表库 前言 AntV F2是一个专注于移动端可视化方案的轻量级图表库它采用声明式语法构建图表UI与React的组件数据可视化前端如何将 Sourcetrail 接入 Qt Creator把插件安装到插件目录并发送光标位置如何将 Sourcetrail 接入 Qt Creator把插件安装到插件目录并发送光标位置 Sourcetrail 是一款通过索引源代码来可视化代码结构的交数据可视化前端上一篇3步构建海量数据实时存储Apache HBase分布式架构实战指南下一篇Gitnuro冲突解决工具内置与第三方方案对比创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

RocketRide Word 工具节点实战指南:基于 Microsoft Graph 与 python-docx 的 OneDrive .docx 读写与并发安全
RocketRide Word 工具节点实战指南:基于 Microsoft Graph 与 python-docx 的 OneDrive .docx 读写与并发安全

【免费下载链接】rocketride-server High-performance AI pipeline engine with a C core and 50 Python-extensible nodes. Build, debug, and scale LLM workflows with 13 model providers, 8 vector databases, and agent orchestration, all from your IDE. Includes VS C… · 2026/9/26 10:11:31

Model Optimizer FAR3D ONNX 后训练量化实战:INT8/FP8 编码器 + TensorRT 11.1 部署与 Argoverse 2 精度评估
Model Optimizer FAR3D ONNX 后训练量化实战:INT8/FP8 编码器 + TensorRT 11.1 部署与 Argoverse 2 精度评估

【免费下载链接】Model-Optimizer A unified library of SOTA model optimization techniques like quantization, distillation, pruning, neural architecture search, speculative decoding, etc. It compresses deep learning models for downstream deployment frameworks… · 2026/9/26 10:11:31

手搓Claude Code-第十章 system_prompt:从零构建可复用的系统提示词配置骨架
手搓Claude Code-第十章 system_prompt:从零构建可复用的系统提示词配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:11:31

玄戒O1官宣后,用VS Code配TaoToken跑通DeepSeek V3论文复现环境
玄戒O1官宣后,用VS Code配TaoToken跑通DeepSeek V3论文复现环境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:25:23

海宁靠谱的二手烘焙设备回收公司透明报价服务商汇总
海宁靠谱的二手烘焙设备回收公司透明报价服务商汇总

海宁市思睿再生资源回收有限公司,江浙沪靠谱二手烘焙设备回收购销服务商海宁市思睿再生资源回收有限公司,简称兵创烘焙设备,是一家立足嘉兴、深耕江浙沪全域的实体化二手烘焙设备、食品厂设备、西餐设备、咖啡水吧设备回收购销服务商&#xf… · 2026/9/26 11:25:16

震惊!2026年AI Agent开发路线图曝光!6个阶段从小白到全栈,TaoToken统一Key配置这波红利必须抓住!
震惊!2026年AI Agent开发路线图曝光!6个阶段从小白到全栈,TaoToken统一Key配置这波红利必须抓住!

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:25:16

AI 的“USB-C 接口”来了:MCP 协议从原理到实战全解析(TaoToken 统一 Key 接入版)
AI 的“USB-C 接口”来了:MCP 协议从原理到实战全解析(TaoToken 统一 Key 接入版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:25:10

微信小程序新生报到系统开发实战:从技术选型到部署
微信小程序新生报到系统开发实战:从技术选型到部署

简介:这是一套基于微信小程序的新生报到系统完整源码与说明文档,主要面向高校计算机专业进行课程设计或毕业设计的学生,也适合需要快速搭建校园迎新报到流程的开发者。系统包含小程序端与管理员端,覆盖新生信息登记、报到进度管理… · 2026/9/26 11:25:10

PaddleOCR轮胎字符识别实战:检测模型、参数调优与后处理全解析
PaddleOCR轮胎字符识别实战:检测模型、参数调优与后处理全解析

简介:面向机器学习课程期末项目的轮胎字符识别工程包,定位于计算机视觉方向课程设计与实践,项目采用EAST/DB算法完成文本检测,配合CRNN与LSTM进行字符识别,能基本提取轮胎胎侧字符,同时保留了花样字体、曲面… · 2026/9/26 11:24:58

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码