LiveCharts2 仪表盘(Gauge)实战指南:用 PieChart 与 GaugeGenerator 构建实心/角度仪表
数据可视化图表库跨平台【免费下载链接】LiveCharts2Beautiful, interactive charts, maps, and gauges. One API for every .NET UI framework.项目地址https://gitcode.com/gh_mirrors/li/LiveCharts2点击查看免费下载LiveCharts2 没有单独的仪表盘控件而是让PieChart同时承载饼图、环形图与仪表盘三种形态其中仪表盘由GaugeGenerator辅助类基于GaugeItem自动生成PieSeriesObservableValue系列集合。本文将以 docs/piechart/gauges.md 为骨架结合仓库源码与示例讲解GaugeItem的 value/builder 两个核心参数、GaugeItem.Background背景系列机制、BuildSolidGauge与BuildAngularGaugeSections两种构建方式以及InitialRotation、MaxAngle、MinValue/MaxValue等配套属性。读完本文你将能够在任意 .NET UI 框架WPF、Avalonia、WinForms、MAUI、Blazor、Uno 等中用同一套代码快速搭建实心仪表、多段仪表、动态仪表和带指针刻度的角度仪表。仪表盘的定位PieChart 的第三种形态在 LiveCharts2 中仪表盘并非独立图表类型而是PieChart控件在特定配置下的渲染结果。其架构可概括为三层控件层PieChart提供InitialRotation、MaxAngle、MinValue、MaxValue、LegendPosition等图表级属性辅助层GaugeGenerator静态类根据传入的GaugeItem列表生成一组带仪表盘语义的PieSeriesObservableValue系列层每个GaugeItem对应一个扇形/环形分段最终由PieChartEngine统一完成测量与绘制。文档明确指出you can also create gauges with thePieChartcontrol从源码看GaugeGenerator生成的就是可被普通饼图画布直接渲染的饼图系列见 GaugeGenerator.cs它reuses all the power and functionality of thePieChartEngineclass因此仪表盘天然继承了饼图的动画、主题、数据标签、图例与悬停等全部能力。GaugeItem仪表盘的构建单元GaugeItem是描述仪表盘中一个元素的载体位于 GaugeItem.cs继承自泛型基类BaseGaugeItemPieSeriesObservableValue。其构造函数接收两个参数参数类型说明valuedouble或ObservableValue该分段在仪表盘上的数值builderActionPieSeriesObservableValue?委托用于配置该数值对应的系列可设置颜色、数据标签大小以及普通饼图系列pieseries.md支持的一切属性value参数有两种重载直接传double或传ObservableValue。后者的价值在于动态更新——ObservableValue实现了值变更通知修改其Value后图表会自动重绘并播放过渡动画详见下文的 Gauge5 示例。builder参数是可选的默认为null但它是仪表盘定制的核心入口。在委托内你可以像操作普通PieSeriesObservableValue一样设置Fill颜色、Stroke、DataLabelsSize、DataLabelsPosition、DataLabelsFormatter、InnerRadius、RelativeInnerRadius、RelativeOuterRadius、MaxRadialColumnWidth、Name图例名称等属性。实心仪表盘BuildSolidGaugeGaugeGenerator.BuildSolidGauge(params GaugeItem[] items)是构建实心仪表盘Solid Gauge即环形/半环形仪表的入口源码见 GaugeGenerator.cs。单值仪表最小示例最简单的情形是只传入一个GaugeItem。仓库示例 Gauge1/View.cs 展示了完整用法pieChart new PieChart { Series GaugeGenerator.BuildSolidGauge( new GaugeItem( 30, // the gauge value series // the series style { series.MaxRadialColumnWidth 50; series.DataLabelsSize 50; })), InitialRotation -90, MinValue 0, MaxValue 100, ... };这里value 30表示当前读数MinValue 0、MaxValue 100划定量程InitialRotation -90让仪表从顶部12 点方向开始绘制MaxRadialColumnWidth 50限制环的径向厚度DataLabelsSize 50放大中心读数。WPF/XAML 场景下有对应的XamlGaugeSeries声明式写法见 Gauge1/View.xaml。多值仪表堆叠分段传入多个GaugeItem时各分段会在同一环上按值占比依次排布形成分段式仪表。例如 Gauge4/View.cs 用三个数值 50 / 80 / 95 构建了三段仪表并分别为每段命名Series GaugeGenerator.BuildSolidGauge( new GaugeItem(50, series SetStyle(Vanessa, series)), new GaugeItem(80, series SetStyle(Charles, series)), new GaugeItem(95, series SetStyle(Ana, series)), new GaugeItem(GaugeItem.Background, series series.Fill null)), InitialRotation -90, MaxAngle 350, MinValue 0, MaxValue 100, public static void SetStyle(string name, PieSeriesObservableValue series) { series.Name name; series.DataLabelsSize 20; series.DataLabelsPosition PolarLabelsPosition.End; series.DataLabelsFormatter point point.Coordinate.PrimaryValue.ToString(); series.InnerRadius 20; series.MaxRadialColumnWidth 5; }注意这里每个分段的InnerRadius 20、MaxRadialColumnWidth 5保持径向厚度一致多段叠加后自然形成并列的同心环带DataLabelsPosition PolarLabelsPosition.End把数值标签放在环带末端。MaxAngle 350则让仪表留出 10° 的缺口而非画满整圈。多值仪表盘效果可参考 gauge4/result.png。动态仪表ObservableValue 驱动如果希望仪表读数实时变化应使用ObservableValue重载并持有其引用之后修改值即可触发自动重绘。示例 Gauge5/View.cs 的核心逻辑var observableValue1 new ObservableValue { Value 50 }; var observableValue2 new ObservableValue { Value 80 }; pieChart new PieChart { Series GaugeGenerator.BuildSolidGauge( new GaugeItem(observableValue1, series { series.Name North; series.DataLabelsPosition PolarLabelsPosition.Start; }), new GaugeItem(observableValue2, series { series.Name South; series.DataLabelsPosition PolarLabelsPosition.Start; })), InitialRotation -90, MaxAngle 270, MinValue 0, MaxValue 100, LegendPosition LegendPosition.Bottom }; // 点击按钮后更新读数图表自动动画过渡 observableValue1.Value _random.Next(0, 100); observableValue2.Value _random.Next(0, 100);这段代码还展示了仪表盘与图例的配合为每个GaugeItem设置series.Name后LegendPosition LegendPosition.Bottom即可显示图例。背景系列GaugeItem.Background 的机制仪表盘通常需要一段底色来衬托当前读数。文档指出将GaugeItem.Background作为value传入GaugeItem会生成一个位于所有仪表分段之后的系列充当图表的背景。从源码看GaugeItem.Background是定义在 BaseGaugeItem.cs 上的常量double.MaxValue构造函数检测到该值时会把IsFillSeriesBuilder置为true从而在GaugeGenerator.Build中被路由到背景系列GaugeGenerator.cs。生成的背景系列具有这些特征ZIndex -1始终垫底IsFillSeries true标记为填充系列IsVisibleAtLegend false不出现在图例中Values填充items.Length - 1个零值用于撑起完整的背景环。示例 Gauge2/View.cs 演示了背景系列的标准用法Series GaugeGenerator.BuildSolidGauge( new GaugeItem(30, series { series.Fill new SolidColorPaint(SKColors.YellowGreen); series.DataLabelsSize 50; series.DataLabelsPaint new SolidColorPaint(SKColors.Red); series.DataLabelsPosition PolarLabelsPosition.ChartCenter; series.InnerRadius 75; }), new GaugeItem(GaugeItem.Background, series { series.InnerRadius 75; series.Fill new SolidColorPaint(new SKColor(100, 181, 246, 90)); // 半透明蓝 })), InitialRotation -225, MaxAngle 270, MinValue 0, MaxValue 100,这里前景段与背景段都设置InnerRadius 75保证两者径向对齐背景用带透明度的SKColor(100, 181, 246, 90)填充形成浅色轨道。若不需要背景如 Gauge4 中令series.Fill null也能得到纯环效果。完整效果见 gauge2/result.png。另一个细节GaugeGenerator.BuildSolidGauge在入参中没有显式传入背景项时会自动补一个默认背景GaugeGenerator.cs这与文档中there is a special value to customize the background series的表述一致——不传GaugeItem.Background也能渲染仪表但传入后才能自定义背景样式。角度仪表盘BuildAngularGaugeSections除实心仪表外GaugeGenerator还提供BuildAngularGaugeSections(params GaugeItem[] items)用于构建角度仪表Angular Gauge即扇形刻度仪表源码见 GaugeGenerator.cs。角度仪表与实心仪表在系列构造上的差异体现在PieChartExtensions.AsSeries内部PieChartExtensions.csSolid 模式每个系列的Values中填充count - 1个占位null/default元素再把真实值插入到与分段序号一致的位置从而让多个分段共享同一圆环Angular 模式每个系列只含自身一个值且额外设置HoverPushout 0、IsHoverable false、DataLabelsPaint null、AnimationsSpeed 0并开启IsRelativeToMinValue true——分段从MinValue起算而不是从 0 起算这是角度仪表刻度语义的关键。角度仪表通常还要叠加指针Needle与刻度Ticks两个视觉元素。示例 AngularGauge/View.cs 与对应的 Blazor 版本 View.razor 完整演示了这套组合var sectionsOuter 130; var sectionsWidth 20; var needle new NeedleVisual { Value 45 }; pieChart new PieChart { Series GaugeGenerator.BuildAngularGaugeSections( new GaugeItem(60, s SetStyle(sectionsOuter, sectionsWidth, s)), new GaugeItem(30, s SetStyle(sectionsOuter, sectionsWidth, s)), new GaugeItem(10, s SetStyle(sectionsOuter, sectionsWidth, s))), VisualElements [ new AngularTicksVisual { Labeler value value.ToString(N1), LabelsSize 16, LabelsOuterOffset 15, OuterOffset 65, TicksLength 20 }, needle ], InitialRotation -225, MaxAngle 270, MinValue 0, MaxValue 100 }; private static void SetStyle( double sectionsOuter, double sectionsWidth, PieSeriesObservableValue series) { series.OuterRadiusOffset sectionsOuter; series.MaxRadialColumnWidth sectionsWidth; series.CornerRadius 0; }三个GaugeItem60 / 30 / 10定义三段刻度区段OuterRadiusOffset 130控制区段离外缘的距离MaxRadialColumnWidth 20控制区段厚度CornerRadius 0关闭圆角以获得规整的刻度条AngularTicksVisual负责刻度线与刻度标签Labeler可自定义标签格式如N1保留一位小数TicksLength控制主刻度线长度NeedleVisual是指针修改其Value即可驱动指针旋转例如点击按钮后needle.Value _random.Next(0, 100)。动态效果可参考 angularGauge/result.gif。配套属性InitialRotation、MaxAngle 与量程仪表盘的形态控制依赖PieChart的三个图表级属性其语义在 docs/piechart/overview.md 中有详细图解属性默认值作用仪表盘常用值InitialRotation0第一段绘制的起始角度度-90顶部起始、-225左下起始、45等MaxAngle360整个图表覆盖的角度度270四分之三圆、350留缺口MinValue/MaxValue—量程下限 / 上限仪表场景通常设为0/100例如InitialRotation -225MaxAngle 270组合出左下开口的标准 270° 仪表Gauge2、AngularGauge 示例InitialRotation 45MaxAngle 270则生成右下开口的形态Gauge3/View.cs。这些属性变更会被 LiveCharts2 的动画系统自动补间过渡。此外GaugeItem的RelativeInnerRadius/RelativeOuterRadius相对半径随控件尺寸缩放与InnerRadius像素半径配合可让分段在环带上错落分层例如 Gauge/ViewModel.cs 中的多段仪表。源码级验证测试与 XAML 等价实现仓库为仪表盘提供了可验证的实现证据快照测试tests/SnapshotTests/AngularGaugeTests.cs 用BuildAngularGaugeSectionsAngularTicksVisualNeedleVisual构建 600×600 的SKPieChart断言渲染结果与基线快照一致其中AngularGaugeAtMinValue用例还专门验证了MinValue边界下刻度透明度规则XAML 声明式等价物在 XAML 框架WPF/Avalonia/WinUI 等中GaugeGenerator的产物对应XamlGaugeSeries、XamlGaugeBackgroundSeries、XamlAngularGaugeSeries三个封装类src/skiasharp/_Shared.Xaml/Series.cs。其中XamlGaugeSeries通过GaugeValue依赖属性绑定到内部ObservableValue值变更经OnGaugeValueChanged自动同步背景系列复用同一套SetupBackgroundGaugeSeries逻辑。因此 Gauge1/View.xaml 可以用纯 XAML 等价实现lvc:PieChart InitialRotation-90 MinValue0 MaxValue100 lvc:PieChart.Series lvc:SeriesCollection lvc:XamlGaugeSeries GaugeValue{Binding Value} DataLabelsSize50 MaxRadialColumnWidth50/ !-- The background series is used to style the gauge background. -- lvc:XamlGaugeBackgroundSeries/ /lvc:SeriesCollection /lvc:PieChart.Series /lvc:PieChart小结LiveCharts2 的仪表盘能力可归纳为一条主线GaugeGenerator构建→GaugeItem元素定义→PieSeriesObservableValue渲染。BuildSolidGauge负责环形分段式实心仪表BuildAngularGaugeSections负责带指针/刻度的角度仪表二者都可通过GaugeItem.Background定制背景轨道通过 value/builder 双参数完成数值绑定与样式定制ObservableValue重载则让仪表支持运行时动态更新。所有能力复用了PieChartEngine的渲染管线因此动画、主题、图例与跨框架一致性均由 LiveCharts2 统一保证。赞分享数据可视化图表库跨平台【免费下载链接】LiveCharts2Beautiful, interactive charts, maps, and gauges. One API for every .NET UI framework.项目地址https://gitcode.com/gh_mirrors/li/LiveCharts2点击查看免费下载相关推荐Plotly.py 仪表盘Gauge Charts实战指南用 Indicator 构建径向仪表盘与 KPI 看板Plotly.py 仪表盘Gauge Charts实战指南用 Indicator 构建径向仪表盘与 KPI 看板 仪表盘Gauge Chart又称 s数据可视化数据分析Windows 11界面太陌生5分钟教你用ExplorerPatcher恢复经典Windows 10体验Windows 11界面太陌生5分钟教你用ExplorerPatcher恢复经典Windows 10体验 还在为Windows 11的全新界面感到不适应吗每桌面应用系统编程F2 仪表盘Gauge组件实战指南角度、刻度与进度展示全解析F2 仪表盘Gauge组件实战指南角度、刻度与进度展示全解析 F2 antv/f2 是蚂蚁集团开源的一款专为移动端设计的优雅、交互式、灵活的图表库数据可视化前端上一篇Claude Coder 成功案例分享从咖啡店网站到企业级应用的完整实现下一篇10个alifd/next常见问题解决方案开发中的坑与填坑指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Ant Design Blazor Steps 组件步骤运行错误(Error 状态)详解:Status 属性的用法与底层实现

Ant Design Blazor Steps 组件步骤运行错误(Error 状态)详解:Status 属性的用法与底层实现

前端UI组件设计系统 【免费下载链接】ant-design-blazor 基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。 项目地址: https://gitcode.com/ant-design-blazor/ant-design-blazor 点击查看 免费下载 导读 本指南围绕 ant-d…

2026/10/12 1:44:57 阅读更多 →
把架构决策固化为可测试的代码:architecture-decision-record 中的 Fitness Functions 实战指南

把架构决策固化为可测试的代码:architecture-decision-record 中的 Fitness Functions 实战指南

【免费下载链接】architecture-decision-record Architecture decision record (ADR) examples for software planning, IT leadership, and template documentation 项目地址: https://gitcode.com/gh_mirrors/ar/architecture-decision-record 点击查看 免费下载 …

2026/10/12 1:43:57 阅读更多 →
re-frame 中 `reg-event-fx` 返回 cofx 而非 fx 的陷阱:理解 effect 与 coeffect 的本质区别

re-frame 中 `reg-event-fx` 返回 cofx 而非 fx 的陷阱:理解 effect 与 coeffect 的本质区别

前端Web框架 【免费下载链接】re-frame A ClojureScript framework for building user interfaces, leveraging React 项目地址: https://gitcode.com/gh_mirrors/re/re-frame 点击查看 免费下载 本文围绕 re-frame 的一个高频 FAQ 展开:为什么在 reg-e…

2026/10/12 1:43:57 阅读更多 →

最新新闻

cli-continues会话管理5大命令:list、scan、inspect、dump、rebuild使用清单

cli-continues会话管理5大命令:list、scan、inspect、dump、rebuild使用清单

【免费下载链接】cli-continues resume any AI coding session in another tool — Claude Code, Copilot, Gemini, Codex, Cursor 项目地址: https://gitcode.com/gh_mirrors/cl/cli-continues 点击查看 免费下载 cli-continues(npm 包名 continues&am…

2026/10/12 8:42:27 阅读更多 →
为对话模型装上持久记忆:claude-mem本地记忆增强工具原理与实践

为对话模型装上持久记忆:claude-mem本地记忆增强工具原理与实践

1. 它是做什么的:一个给对话工具装上记忆的中间层 如果你经常用 Claude 这类对话模型处理长周期任务,大概率遇到过同一个尴尬局面:上下文窗口明明还没撑爆,但模型已经把三天前你交代的关键背景忘得一干二净。尤其是跨会话的场景—…

2026/10/12 8:42:27 阅读更多 →
AnyPS5 深度解析:PS5 手柄映射与串流技术实战

AnyPS5 深度解析:PS5 手柄映射与串流技术实战

1. 项目缘起与核心定位第一次看到“AnyPS5”这个命名,我脑子里蹦出来的第一反应是:这大概率是一个围绕 PlayStation 5 生态做“泛化能力扩展”的项目。为什么这么说?因为“Any”这个前缀在技术圈里通常意味着“把原本封闭或单一场景的能力&am…

2026/10/12 8:42:27 阅读更多 →
多指标定量测定与等级预测:PCA、OPLS-DA、FA、熵权TOPSIS实战

多指标定量测定与等级预测:PCA、OPLS-DA、FA、熵权TOPSIS实战

做多指标定量测定的人,十有八九都会被同一个问题卡住:指标测了一堆,数据表格填得满满当当,但领导或者审稿人一句“所以它到底属于哪个等级”,就让你不知道怎么回。项目名称里这串组合——PCA、OPLS-DA、FA、熵权TOPSIS…

2026/10/12 8:42:27 阅读更多 →
std::allocator::destroy 被删了:析构与释放分离的演进与迁移指南

std::allocator::destroy 被删了:析构与释放分离的演进与迁移指南

警告刷屏、编译报错、内存泄漏&#xff0c;三种看着毫不相干的 bug&#xff0c;可能都源自同一个函数&#xff1a;std::allocator<T>::destroy。它在 C17 里被标了弃用&#xff0c;C20 里被直接删除&#xff0c;很多老项目因此得翻出一堆调用点来改。但真正把它吃透之后你…

2026/10/12 8:42:27 阅读更多 →
CLI-Anything 实战:一条命令把任意软件变成 AI Agent 原生工具,TaoToken 统一 Key 怎么接?

CLI-Anything 实战:一条命令把任意软件变成 AI Agent 原生工具,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/10/12 8:41:26 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天&#xff0c;画面可以做到绝对的锐利、平滑与无瑕。然而&#xff0c;当一张秋日手账插画或拍立得照片过于“平整无瑕”时&#xff0c;往往会散发出一种冰冷生硬的“数码塑料感&#xff08;Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中&#xff0c;横排&#xff08;Horizontal Layout&#xff09;早已经成为了绝对的主流。然而&#xff0c;当我们翻开泛黄的线装古籍、宋版木刻诗集&#xff0c;或是欣赏一张茶道雅集的手写便签时&#xff0c;那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点&#xff0c;很多人心里都会悄悄亮起一盏警示灯。 在心理学上&#xff0c;这种现象有一个专门的称谓——“周日夜晚焦虑症&#xff08;Sunday Scaries&#xff09;”。明天又是周一&#xff0c;闹钟又要重新在七点响彻卧房&#xff1b;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式: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/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/11 14:36:54 阅读更多 →