前端图表库数据可视化【免费下载链接】uPlot A small, fast chart for time series, lines, areas, ohlc bars项目地址https://gitcode.com/gh_mirrors/up/uPlot点击查看免费下载本报告解读 uPlot 仓库中 docs/investigations/coverage-gaps.md 这一内部审计文档它基于 2026-09-17 的工作树通过npm testNode 26.8.21,011 项通过耗时 14 秒生成的 Istanbul 覆盖率数据逐文件、逐分支地列出了当前测试套件尚未覆盖的代码路径并为每个缺口给出了具体的补测优先级与测试策略。读者读完本文后可以掌握 uPlot 测试基础设施的运行方式npm test的完整调用链、各源码模块的真实覆盖率基线以及内置光标选中、同步拖拽、faceted 数据与动态 series、路径构建器、日期格式化等核心模块中高优先级缺口的具体补测方案。审计基础与方法论审计快照与证据来源该报告描述的是 2026-09-17 的当前工作树其状态包含e27e4092cfc67c7c57d7b7e1c39a08fae1cfb143之上未提交的源码与测试改动。上一份报告描述的是一个 614 项测试的历史快照已经不能代表当前测试套件因此本次审计完全以重新执行测试得到的证据为准。审计的唯一证据命令是npm test该命令使用 Node 26.8.2 执行结果为1,011 项测试全部通过耗时 14 秒并生成了一份全新的 Istanbul 覆盖率报告。报告中特别强调了三点可信度边界测试运行器在每次执行前会删除.nyc_output目录见 scripts/test.mjs 中rmSync(coverageDir, { recursive: true, force: true })因此不会复用历史覆盖率数据Bun 验证未运行报告对 Bun 兼容性或 Bun 下的覆盖率不做任何声明覆盖率只代表代码被执行过不代表断言质量——某一行被执行但断言不严格与完全未执行是不同的风险等级。npm test 的底层调用链从 package.json 可以看到test脚本指向node ./scripts/test.mjs。scripts/test.mjs 的逻辑是根据运行时是 Bun 还是 Node 选择不同的覆盖率输出目录.nyc_output/bun或.nyc_output通过NODE_OPTIONS--import ./scripts/register-hooks.mjs注入 Istanbul 插桩钩子Bun 下则使用--preload调用mocha来自mocha/bin/mocha.js执行全部测试最后运行scripts/report-coverage.mjs生成覆盖率报告。package.json中nyc配置的include为dist/**/*.esm.js与src/**/*.jsexclude为src/paths/catmullRomCentrip.js该路径构建器不在本次审计范围内。因此本文下面所有源码引用均以src/目录为准。当前覆盖率总览全局与核心文件指标报告给出了三个层级的覆盖率AreaStatementsBranchesFunctionsLinesAll files94.47%88.09%92.96%94.39%src94.24%88.48%91.98%94.17%src/paths95.62%85.82%98.36%95.54%主要源文件的覆盖率FileStatementsBranchesFunctionsLinessrc/uPlot.js93.46%88.54%94.94%93.41%src/utils.js95.57%91.25%92.59%95.60%src/fmtDate.js82.17%59.55%71.42%81.81%src/opts.js98.97%96.13%95.74%98.92%src/dom.js100%93.33%100%100%注意 src/fmtDate.js 是分支覆盖率最低的核心模块59.55%而 src/dom.js 达到了语句与行覆盖率双 100%。src/opts.js仅剩372与500-501两处未覆盖分别是无调用方的mkDate()与默认cursor.drag.click的传播抑制分支。全局缺口总表报告用一张表格概括了各领域的当前状态、主要剩余缺口与优先级AreaCurrent assessmentMain residual gapsPriorityBuilt-in cursor selectionLarge direct gapNon-null search, hover bias, proximity rejectionHighDynamic seriesaddSeries()已覆盖delSeries()未覆盖带 legend 与 cursor 状态的删除、按索引插入HighDrag and synchronization基础拖拽与一个同步 X 用例已覆盖同步 Y、key 不匹配、旋转、drag.uniHighDate formatting and zones常见路径被间接覆盖特定 token 与DateZoned分支MediumPath builders语句覆盖高但分支有缺口抽稀 null、垂直路径、扩展、短样条MediumScale, layout, and bands远强于旧报告所述依赖缩放、band clip、轴边框、range guardsMedium to lowData joining核心行为已有直接测试顺序检查中的 null 填充 X 列LowBrowser lifecycle部分状态变更有 Happy DOM 测试原生 DPR、全局 resize/scroll、媒体查询Browser integrationDebug and uncommon APIs小且孤立的缺口IDs、日志、band 变更、罕见回调形式Low自旧快照以来的实质变化报告明确指出旧报告严重低估了多个领域这些领域如今已有直接覆盖test/cursor-drag.mjs 的 41 项测试覆盖了 DPR 1 与 DPR 2 下的 X、Y、XY 鼠标拖拽拖拽测试覆盖正向/反向移动、反转 scale、阈值、plot 外释放、双击重置、首选的drag.setRangeAPI 以及已废弃的布尔drag.setScale别名一个同步 X 拖拽用例现在能触达目标图表并校验每个图表的回调test/cursor-points.mjs 覆盖共享与逐 series 的点、DPR 变化、隐藏点、旋转轴与 mode 2mode 2 初始化与 scale 扫描在 scale、cursor、asinh 与 issue 测试中有广泛直接覆盖addSeries()在 aligned 与 faceted 两种测试中都有执行但显式指定索引插入未执行test/join.mjs 覆盖有序/无序输入、null 模式、TypedArray、大规模合并与输入不可变性layout 与 scale-range 测试套件覆盖了大量 resize、range、scan、隐藏轴与延迟提交deferred-commit场景。这些新增直接推翻了旧报告中基础拖拽未测、mode 2 初始化未测、数据 join 未测、隐藏轴行为未测等宽泛结论。内置光标选中最高优先级缺口默认非 null hover 选择逻辑默认的cursor.dataIdx实现位于 src/uPlot.js。该实现的核心流程结合 src/uPlot.js 的上下文为构造skip集合包含void 0以排除对齐伪影并读取cursor.hover.prox与cursor.hover.bias默认0当bias 0 || bias -1时从光标索引向左扫描寻找第一个非 null 值nonNullLft当bias 0 || bias 1时向右扫描nonNullRgt若两侧都有值当启用prox时按像素距离lftDelta rgtDelta选择更近一侧并分别与_prox阈值比较后才接受候选未启用prox时直接选择索引距离更近的一侧若仅一侧有值则直接选中该侧当最近的 X 点本身非 null 但像素距离超过prox上限时返回null拒绝该候选对应 src/uPlot.js 的else if (withProx)分支。当前测试套件虽然进入了缺失值路径但没有执行大部分选择逻辑。报告列出的未覆盖语句为src/uPlot.js:1087-1088左侧候选通过prox阈值src/uPlot.js:1095-1096仅一侧有值时的选择src/uPlot.js:1101-1113withProx下按像素距离选择最近侧src/uPlot.js:1117cursor._lock初始化src/uPlot.js:1125focus 对象合并src/uPlot.js:1127-1128cursorFocus/cursorOnePt判定残余用例包括向左/向右搜索非 null 值、两侧都有值时选最近侧、仅一侧有值时选唯一侧、cursor.hover.bias取-1/0/1、通过cursor.hover.prox接受或拒绝候选、以及当最近非 null X 点的像素距离超过 prox 上限时拒绝。报告特别提醒nearest-non-null相关 demo 测试如 demos/nearest-non-null.html使用的是自定义 cursor 行为并不能证明默认实现。建议的补测方式是构造一个小的 Happy DOM 集成表格通过setCursor()或鼠标事件驱动光标再断言cursor.idxs与 legend 值。非零 focus 偏差常规focus.bias: 0路径已有覆盖但 src/uPlot.js 的非零偏差逻辑未覆盖。该逻辑实际位于updateCursor的 series 循环内见 src/uPlot.js在focus.prox 0时启用比较鼠标 Y 值与候选 series 值的符号当二者同号时才可能成为最近 series若bias 1偏向远离零的一侧bias -1偏向靠近零的一侧——正如源码注释所说with a focus bias, we will never cross zero when prox testing。未覆盖语句为src/uPlot.js:2969、2971-2972、2976、2981-2982。建议补充聚焦用例正/负的 series 值光标值与 series 值在零的同侧光标值与 series 值在零的异侧偏向零bias 向 0与远离零bias 向 1两种情况。拖拽选择与同步从大缺口到具体分支现已覆盖的行为test/cursor-drag.mjs通过 41 项测试提供了大量集成覆盖包括X-only、Y-only 与 XY 拖拽正向与反向拖拽DPR 1 与 DPR 2反转的 scale 方向drag.dist与零位移处理当首选drag.setRange为 false 时保留选区通过首选drag.setRange回调进行选区细化与取消已废弃的纯布尔drag.setScale别名的 true/false 兼容性在 plot 外释放鼠标resize 与轴折叠后的几何刷新双击重置范围两个水平图表间的同步 X-only 拖拽。因此基础拖拽是普遍缺口的旧结论已不成立。同步选择投影的剩余缺口同步选择的投影逻辑位于 src/uPlot.js对应拖拽同步分支实际在src/uPlot.js的setRange/同步回调区域报告引用 3080-3144 作为同步选择投影。现有同步测试只到达了水平方向 X key 匹配的路径。当前缺口包括src/uPlot.js 的同步 Y 选择src/uPlot.js 与3124-3130的旋转源选择sx.ori为垂直时的水平/垂直值交换src/uPlot.js 的非匹配 X key 与全宽重置src/uPlot.js 源无激活拖拽维度与选区清除两个维度的 scale-key 匹配/不匹配回调。此外同步光标投影src/uPlot.js:3302-3349也缺少旋转源与无 scale-key 的用例。旋转与单向拖拽缺口水平拖拽路径覆盖很强但以下分支未被执行src/uPlot.js 的旋转拖拽维度交换src/uPlot.js 的drag.uni低于阈值时的方向选择src/uPlot.js 的旋转 X 选择src/uPlot.js 的旋转 Y 选择src/uPlot.js 的旋转拖拽轴映射与 src/uPlot.jsmouseLeave()期间垂直边缘吸附。报告建议直接扩展现有拖拽测试框架——它已能提供稳定的 plot 几何与鼠标事件。更小的 cursor 生命周期缺口旧报告称大多数 cursor 生命周期函数未覆盖这一论断已不再正确。mouseMove()、mouseUp()、mouseLeave()、dblClick()现在都运行于集成测试中。剩余分支包括src/uPlot.js、3492-3493、3546-3547的锁定光标cursor._lock提前返回src/uPlot.js 的同步 focus 映射src/uPlot.js 的内部 DPR 监听器。这些分支优先级低于默认 hover 选择与同步拖拽投影。Faceted 数据与动态 series现状mode 2 不再是宽泛缺口Mode 2faceted初始化不是普遍缺口。现有测试已能构造 faceted 图表并覆盖 scale 扫描、cursor 点、范围与拖拽重置。addSeries()src/uPlot.js也有 aligned 与 faceted 两种直接覆盖但按传入索引插入的分支src/uPlot.js 的si si null ? series.length : si及后续splice(si, 0, opts)仍未覆盖。delSeries()完全未覆盖delSeries()位于 src/uPlot.js目前没有任何覆盖。该函数按序执行从series数组移除条目使 band group 缓存失效invalidateBandGroups()移除 legend 的 values 条目FEAT_LEGEND legend.values.splice(i, 1)并刷新 legend移除activeIdxs中的光标索引若光标启用移除 cursor-point DOM 元素cursorPts.splice(i, 1)[0].remove()并同步cursorPtsLft/cursorPtsTop触发fire(delSeries, i)hook 通知。注意该函数不会移除 scale也没有独立的 faceted 清理逻辑。测试必须断言已实现的公开行为而不是假设存在这种清理。报告建议添加一个启用 legend 与 cursor 的 aligned 测试、一个 mode 2 冒烟测试并覆盖从 series 数组中间位置删除的场景同时覆盖带索引的addSeries()插入断言 series 顺序、legend 顺序、cursor 数组、hooks 以及setData()之后的行为。Mode 2 可见性重定范围src/uPlot.js是另一个独立的小缺口。数据 join 与排序低优先级残留join() 核心行为已被直接覆盖test/join.mjs 直接覆盖了join()的主要行为相同 X 列与保留的列引用相同与不同的无序 X 列Typed X/Y 列部分与不相交的重叠每张表多个 Y series显式null与undefined值NULL_REMOVE、NULL_RETAIN、NULL_EXPAND三种模式空表与空 series输入不可变性100 张表的共享有序合并路径与旧算法的随机化对比。结论核心 join 行为已覆盖不应再保持高优先级。isAsc() 的小残留isAsc()位于 src/utils.js套件未执行以下分支src/utils.js 的前导 nullish X 值跳过循环src/utils.js 的尾部 nullish X 值跳过循环src/utils.js 的全 nullish 或单一被 null 包围的值直接返回true。报告的建议很务实只有当null 填充的 X 列是被支持的输入时才补一个紧凑测试否则应在文档中说明或直接拒绝该输入而不是为了提升百分比去补纯数字测试。日期格式化与时区分支覆盖率最低的模块未覆盖的 token 回调src/fmtDate.js 的覆盖率为语句 82.17%、分支 59.55%、函数 71.42%、行 81.81%是核心模块中分支覆盖率最低的。常见格式化与时区路径通过 demos 与图表测试运行真正未覆盖的 token 回调比旧报告更具体{MMMM}src/fmtDate.js完整月份名{WWWW}与{WWW}src/fmtDate.js完整/缩写星期名{HH}与{H}src/fmtDate.js补零/不补零的小时{AA}src/fmtDate.js大写 AM/PM{a}src/fmtDate.js{m}src/fmtDate.js{s}src/fmtDate.js。{fff}毫秒 token 已覆盖自定义名称与模板装配src/fmtDate.js 的fmtDate(tpl, names)也已有覆盖因此不是宽泛缺口。DateZoned 的时区残留DateZonedsrc/fmtDate.js剩余时区缺口包括src/fmtDate.js 的本地时区快速路径tz null || tz localTz时直接返回Datesrc/fmtDate.js 的拷贝构造参数为DateZoned实例时复制tz/#str/#utcsrc/fmtDate.js 的DateZoned.#get()中 UTC-backed getter 分支this.#utc ? utcMeth.call(this) : ...src/fmtDate.js 的零偏移GMT归一化f.endsWith(GMT)时补00:00src/fmtDate.js 的 zonedgetDay()根据瑞典语星期缩写首字母推断星期如sön→0、mån→1src/fmtDate.js 的 zonedgetTimezoneOffset()从格式化字符串尾部解析偏移。死代码不要为了覆盖率去测leapYear()src/fmtDate.js是私有函数且没有调用方mkDate()src/opts.js同样无调用方其未覆盖语句在 src/opts.js。报告明确要求不要通过人为手段让测试触达这些死助手函数如果它们仍然必要应在单独的源码变更中移除或重新接入。日期 token 与DateZoned方法的补测应使用表驱动单元测试且不需要图表。路径构建器高语句覆盖下的分支缺口路径语句覆盖很高但分支覆盖只有 85.82%。补测原则保持路径测试小而聚焦并对比记录的Path2D命令。线性路径与抽稀decimationsrc/paths/linear.js 语句覆盖 93.68%、分支覆盖 80.76%。未覆盖语句为93-94、107、109-110、119全部属于抽稀路径decimate分支即idx1 - idx0 xDim * 4时启用见 src/paths/linear.js而非普通非抽稀路径。目标用例复用的像素桶pixel bucket内出现null新像素桶起始处出现null最后一个桶仍需绘制其 min/max 累加器反向或垂直抽稀方向分支未覆盖。旧报告所有spanGaps、fill 与 clipping 行为都未测的说法过于宽泛已被否定。阶梯路径src/paths/stepped.js 语句覆盖 92.64%、分支覆盖 72.54%。未覆盖语句为18、45-46、78-79主要目标空输入或全 null 输入extend: true且align: -1extend: true且align: 1垂直或反向方向spanGaps: true。样条src/paths/monotoneCubic.js 未覆盖语句为13、20、48分别代表少于两个点、恰好两个点、计算出的斜率非有限值如重复的 X 坐标。src/paths/spline.js 未覆盖语句为10与27-29需要补全 null 与垂直方向的包装器用例。柱状图与共享路径工具src/paths/bars.js 是自定义柱状显示几何的 value-unit 宽度分支src/paths/utils.js 反向 band 裁剪src/paths/utils.js 合并重复的 gap 起始点src/paths/utils.js 反向 gap 扫描src/paths/utils.js 垂直 Bézier 辅助函数。这些都是聚焦的分支测试不需要构造庞大的路径选项矩阵。Scale、布局与工具函数的边缘当前 layout 与 range 测试套件已让旧报告的宽泛缺口清单过时——它们覆盖了大量 resize、隐藏轴、scan、range-policy 与延迟提交路径。src/uPlot.js 的残留聚类src/uPlot.js 轴回退到 series scaleaxis 指定了不存在的 scale 时回退见initAxis中sc null的处理src/uPlot.jssetData()后非 auto 的 X 范围src/uPlot.js 依赖 scale 的传播src/uPlot.js 可见窗口外的 null 搜索src/uPlot.js band 裁剪组合src/uPlot.js 非正的轴维度src/uPlot.js 轴边框绘制src/uPlot.js 延迟的初始选择src/uPlot.js 反转、极小与单索引 ordinal range guardssrc/uPlot.js faceted 可见性重定范围。src/utils.js 的残留语句src/utils.jsrangeAsinh()的零端点src/utils.jshasData()的全 null 结果src/utils.js 非零的折叠范围回退src/utils.jsnumDigits()src/utils.jscmpObj()src/utils.js TypedArray 复制。报告建议只针对已文档化的契约或历史上的故障补测试不要为了提升覆盖率构建宽泛的组合矩阵。浏览器生命周期行为需要真实浏览器集成测试src/dom.js 已实现语句与行覆盖率双 100%剩余分支位置为25-28与123。未测用例包括DPR 通知但 DPR 未变化DPR 变化后移除之前的 media-query 监听器启用 capture 时的off()。相关 src/uPlot.js 缺口src/uPlot.js 全局矩形失效src/uPlot.js 全局 DPR 传播src/uPlot.js 图表 DPR 监听器。现有测试覆盖了显式 resize、直接setPxRatio()、cursor 矩形刷新与从cursorPlots移除图表旧报告错误地声称 cursor 追踪移除未覆盖。关键结论是Happy DOM 无法复现原生 media-query 与布局行为全局 resize、scroll 与 DPR 变化应使用真实浏览器的集成测试如 test/e2e 目录所承载的方案。Debug 与不常见 API 路径低价值缺口包括内部log()src/uPlot.js显式根opts.idsrc/uPlot.js拖拽后的 click 回调src/uPlot.js默认cursor.drag.click的传播抑制src/opts.jssetBand()src/uPlot.jsassign(bands[bi], opts)带索引的addBand()/delBand()分支src/uPlot.js 与2608无挂载目标的构造器初始化src/uPlot.js。报告建议除非有已报告的问题触达这些路径否则保持 debug 与防御性路径未覆盖即可当 band 行为发生变化时公开的 band 变更mutationAPI 是合理的例外。推荐的补测顺序报告按投入产出比给出了明确优先级为内置的非 nullcursor.dataIdx行为添加表驱动集成测试添加 aligned 与 faceted 的delSeries()测试以及带索引的addSeries()覆盖扩展拖拽测试框架覆盖同步 Y、key 不匹配、旋转与drag.uni为未覆盖的公开日期 token 与DateZoned方法添加单元测试添加聚焦的路径测试抽稀 null、阶梯扩展、垂直样条与反向工具函数仅为已文档化的行为或已知回归添加 scale、band 或 layout 测试将原生 DPR、resize 与 scroll 行为保留在浏览器集成测试套件中。最后一条总原则贯穿始终不要仅为提升覆盖率百分比而去瞄准死助手函数、debug 路径或防御性分支——覆盖率报告的价值在于暴露真实的行为风险而不是制造一个好看的百分比数字。赞分享前端图表库数据可视化【免费下载链接】uPlot A small, fast chart for time series, lines, areas, ohlc bars项目地址https://gitcode.com/gh_mirrors/up/uPlot点击查看免费下载相关推荐Pencil Project单元测试覆盖率 Istanbul配置与报告分析Pencil Project单元测试覆盖率 Istanbul配置与报告分析 Pencil Project作为一款开源的GUI原型设计工具其代码质量直接影响用桌面应用Blockly 单元测试覆盖率工具istanbul 配置与报告分析Blockly 单元测试覆盖率工具istanbul 配置与报告分析 在现代软件开发中单元测试覆盖率是衡量代码质量的重要指标之一。它能够帮助开发团队识别未被测前端低代码UI组件PS3游戏加载革命如何用webMAN-MOD打造你的终极游戏中心PS3游戏加载革命如何用webMAN MOD打造你的终极游戏中心 你是否曾经为PS3游戏管理而烦恼每次都要插拔硬盘、拷贝文件或者面对复杂的安装流程感到头疼后端嵌入式上一篇my-arsenal-of-aws-security-tools离线更新机制空气隔离环境工具升级方案下一篇微型椭圆曲线加密库终极指南如何在资源受限设备上实现高性能ECDH和ECDSA创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考