尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Textual Sparkline 控件详解:在终端中用迷你条形图可视化数值数据

发布时间:2026/9/20 8:47:22

资讯中心
01
ARTICLE

Textual Sparkline 控件详解:在终端中用迷你条形图可视化数值数据

Textual Sparkline 控件详解:在终端中用迷你条形图可视化数值数据
Textual Sparkline 控件详解在终端中用迷你条形图可视化数值数据【免费下载链接】textualThe lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.项目地址: https://gitcode.com/gh_mirrors/te/textualSparkline迷你趋势图是 Textual 自 0.27.0 起内置的一个轻量级控件用于把一维数值序列压缩成由多根条形组成的小图常用于实时监控、数据面板或仪表盘的紧凑式可视化场景。阅读本篇后你将掌握 Sparkline 的分桶bucket渲染原理、如何用summary_function自定义每根条形的高度、如何通过组件类与构造参数定制颜色以及如何把数据接入响应式系统实现动态更新。Sparkline 是什么Sparkline 是一种不显示坐标轴、仅用条形高度传达数据趋势的紧凑图表。Textual 的Sparkline控件在终端中把一组数值如 CPU 占用率、网络延迟、传感器读数渲染为一行或多行小条形图数据越多越密集视觉上近似迷你波形。在 src/textual/widgets/_sparkline.py 中控件的定义非常简洁class Sparkline(Widget): A sparkline widget to display numerical data.官方文档 docs/widgets/sparkline.md 明确标注了它的两个基础特性不可聚焦Focusable: 否不是容器Container: 否这意味着它纯粹是一个只读展示控件不响应键盘焦点也不能挂载子控件。它不发送任何消息Messages: 无也没有任何按键绑定Bindings: 无交互完全交给数据驱动。快速上手基础示例与分桶逻辑官方文档的基础示例揭示了 Sparkline 最核心的机制数据会被切分成大小相等的桶chunk每个桶渲染为一根条形而条形数量由控件宽度决定。先看数据文件 docs/examples/widgets/sparkline_basic.pyfrom textual.app import App, ComposeResult from textual.widgets import Sparkline data [1, 2, 2, 1, 1, 4, 3, 1, 1, 8, 8, 2] # 共 12 个数据点 class SparklineBasicApp(App[None]): CSS_PATH sparkline_basic.tcss def compose(self) - ComposeResult: yield Sparkline( data, summary_functionmax, # 每根条形代表该桶的最大值 ) app SparklineBasicApp() if __name__ __main__: app.run()配套样式 docs/examples/widgets/sparkline_basic.tcssScreen { align: center middle; } Sparkline { width: 3; /* 宽度设为 3得到 3 个桶 */ margin: 2; }配合summary_functionmax后渲染结果如下█ ▄ █ ▂ █对比例子的执行逻辑共有12 个数据点[1, 2, 2, 1, 1, 4, 3, 1, 1, 8, 8, 2]。通过 CSS 把宽度设为3因此数据被均分为3 个桶每个桶恰好 4 个数据点。每根条形的高度取自该桶经summary_function计算后的值这里使用max即桶内最大值。三个桶的最大值分别是2、4、8所以第一根条形的高度是第二根的一半、第二根是第三根的一半——这正是示例输出的由来。这段逻辑在渲染层 src/textual/renderables/sparkline.py 的_buckets方法中有精确实现classmethod def _buckets(cls, data: list[T], num_buckets: int) - Iterable[Sequence[T]]: bucket_step Fraction(len(data), num_buckets) for bucket_no in range(num_buckets): start int(bucket_step * bucket_no) end int(bucket_step * (bucket_no 1)) partition data[start:end] if partition: yield partition值得注意的是分桶使用Fraction精确计算边界避免浮点误差导致桶大小不一致且每个桶都会独立调用summary_function见 src/textual/renderables/sparkline.py把桶内数据压缩成一个代表值。自定义汇总函数决定每根条形的高度summary_function是 Sparkline 最灵活的扩展点它决定一个桶最终以什么值参与绘图。官方文档用 docs/examples/widgets/sparkline.py 演示了三种内置行为import random from statistics import mean from textual.app import App, ComposeResult from textual.widgets import Sparkline random.seed(73) data [random.expovariate(1 / 3) for _ in range(1000)] class SparklineSummaryFunctionApp(App[None]): CSS_PATH sparkline.tcss def compose(self) - ComposeResult: yield Sparkline(data, summary_functionmax) # 每根条形显示桶内最大值 yield Sparkline(data, summary_functionmean) # 每根条形显示桶内平均值 yield Sparkline(data, summary_functionmin) # 每根条形显示桶内最小值 app SparklineSummaryFunctionApp() if __name__ __main__: app.run()配套样式 docs/examples/widgets/sparkline.tcss 仅需把宽度拉满即可让三行图铺满屏幕Sparkline { width: 100%; margin: 2; }三种汇总函数在同一份 1000 个指数分布随机数上呈现出明显差异max生成的图最饱满、min最瘦小、mean介于两者之间。这提醒我们选对汇总函数等于选择了图表想强调的数据特征峰值、典型值还是低谷。自定义函数同样简单只要满足签名Callable[[Sequence[float]], float]返回桶的代表值即可。例如想突出波动幅度可以写def range_value(bucket): return max(bucket) - min(bucket) yield Sparkline(data, summary_functionrange_value)用组件类定制颜色min/max 双色插值Sparkline 的颜色不是单色的而是在最小值颜色与最大值颜色之间按数值大小插值。官方文档的第三个示例 docs/examples/widgets/sparkline_colors.py 用正弦函数生成数据并堆叠了 10 个 Sparklinefrom math import sin from textual.app import App, ComposeResult from textual.widgets import Sparkline class SparklineColorsApp(App[None]): CSS_PATH sparkline_colors.tcss def compose(self) - ComposeResult: nums [abs(sin(x / 3.14)) for x in range(0, 360 * 6, 20)] yield Sparkline(nums, summary_functionmax, idfst) yield Sparkline(nums, summary_functionmax, idsnd) # ... 其余 id 依次为 trd / frt / fft / sxt / svt / egt / nnt / tnt app SparklineColorsApp() if __name__ __main__: app.run()颜色通过两个组件类Component Classes控制在 docs/examples/widgets/sparkline_colors.tcss 中以#id .component-class的写法按控件分别定制#fst .sparkline--max-color { color: $success; /* 较大值偏向绿色 */ } #fst .sparkline--min-color { color: $warning; /* 较小值偏向黄色 */ } #fft .sparkline--max-color { color: $accent; } #fft .sparkline--min-color { color: $accent 30%; /* 支持透明度修饰符 */ }这 10 行图分别演示了$success、$warning、$error、$accent、$primary及其 30% 透明变体的组合包括大值深色/小值浅色与大值浅色/小值深色两种方向。从 src/textual/widgets/_sparkline.py 可以确认组件类只有两个且只对color生效设置其他样式属性无效| 组件类 | 含义 | | :- | :- | |sparkline--max-color| 数据中较大值所用的颜色 | |sparkline--min-color| 数据中较小值所用的颜色 |控件还内置了默认样式见 src/textual/widgets/_sparkline.py不写任何 CSS 也能直接使用Sparkline { height: 1; } Sparkline .sparkline--max-color { color: $primary; } Sparkline .sparkline--min-color { color: $primary 30%; }即默认高度为 1 行、最大值取主题主色、最小值取主色 30% 透明度的渐变效果。构造函数参数用 Python 代码直接指定颜色除了 CSS 组件类Sparkline的构造函数还接受min_color与max_color两个参数见 src/textual/widgets/_sparkline.py适合在compose中动态决定配色yield Sparkline( data, min_colorcyan, # 接受任意可被 Color.parse 解析的颜色字符串 max_colormagenta, )__init__的完整签名如下def __init__( self, data: Sequence[float] | None None, *, min_color: Color | str | None None, max_color: Color | str | None None, summary_function: Callable[[Sequence[float]], float] | None None, name: str | None None, id: str | None None, classes: str | None None, disabled: bool False, ) - None:传入None默认值时颜色回退到 CSS 组件类定义的值传入颜色字符串时会经Color.parse解析传入的颜色还会与控件的背景色做叠加混合base color见 src/textual/widgets/_sparkline.py确保条形在非默认背景上也清晰可辨。响应式属性与动态数据更新Sparkline 仅有两个响应式属性见 docs/widgets/sparkline.md 的 Reactive Attributes 一节及 src/textual/widgets/_sparkline.py名称类型默认值说明dataSequence[float] \| NoneNone由 Sparkline 表示的数值数据summary_functionCallable[[Sequence[float]], float]max计算每根条形高度的函数两者都是响应式reactive属性意味着可以直接赋值触发自动重绘self.query_one(Sparkline).data new_measurements # 更新数据图表立即刷新由于summary_function同样是响应式的运行时切换汇总策略如从max切到mean也会即时生效。配合 Textual 的定时器或 Worker就能实现实时刷新的迷你监控图。响应式系统的通用机制可参考 docs/guide/reactivity.md。渲染原理八级条形与桶内高度归一化从 src/textual/renderables/sparkline.py 可以看到条形高度由 8 个 Unicode 分级字符渲染BARS ▁▂▃▄▅▆▇█绘制流程src/textual/renderables/sparkline.py大致为计算数据的最小值与最大值extent maximum - minimum or 1数据全相等时避免除零对每个桶调用summary_function得到代表值计算height_ratio (partition_summary - minimum) / extent将其归一化到 01按归一化比例映射到BARS分级字符并依该值与 min/max 颜色的相对位置做颜色插值。因此height属性默认 1最大可配多行决定字符的纵向堆叠分辨率width决定桶数。把高度调高可以得到更细腻的波形例如 CSS 中写height: 3时每个数据位置最多能渲染出 8×3-1 级高度差异。渲染层同样是一个独立的 Rich renderabletextual.renderables.Sparkline默认 min 色为绿色、max 色为红色见 src/textual/renderables/sparkline.py也可单独用于自定义渲染场景。边界情况与测试佐证渲染层对空数据与单点数据做了专门处理src/textual/renderables/sparkline.py空数据输出整行▁最低级别条形并保持 min 色控件不会崩溃单点数据直接输出整行█并保持 max 色。仓库在 tests/renderables/test_sparkline.py 中对该渲染层进行了覆盖测试验证分桶、分级字符与颜色插值的正确性控件层的响应式属性与默认 CSS 则由 src/textual/widgets/_sparkline.py 定义。若想进一步了解如何把 Sparkline 组合进Horizontal等容器可参考 docs/widgets/containers.md。速查小结定位只读展示控件不可聚焦、非容器、无消息、无绑定自 Textual 0.27.0 起提供数据映射宽度 桶数数据等分入桶每桶经summary_function压缩为一个代表值汇总函数默认max可传mean、min或任意Sequence[float] - float自定义函数颜色定制优先用组件类sparkline--max-color/sparkline--min-color写 CSS也可用构造函数参数min_color/max_color直接指定两者均在 min/max 之间插值动态更新直接赋值响应式属性data与summary_function即可触发重绘适合实时数据场景。【免费下载链接】textualThe lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.项目地址: https://gitcode.com/gh_mirrors/te/textual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。