前端UI组件数据可视化【免费下载链接】blessed-contribBuild terminal dashboards using ascii/ansi art and javascript项目地址https://gitcode.com/gh_mirrors/bl/blessed-contrib点击查看免费下载blessed-contrib 是一个基于 Node.js 的终端仪表盘Dashboard构建库它扩展了 blessed 的窗口组件体系并借助 drawille 等底层画布能力将折线图、柱状图、仪表盘、环形图、世界地图等图表组件搬进纯文本终端。本文以项目 README 为主线结合仓库源码lib/、examples/逐项讲解安装、通用使用模式、全部 Widget 的配置参数与数据格式并给出 Grid、Carousel 布局与完整示例读完即可在 SSH、串口或任意 ASCII 终端中搭建自己的实时监控面板。项目概览与核心设计blessed-contrib 的定位非常明确使用 ASCII/ANSI 艺术和 JavaScript 构建终端仪表盘或任何其他应用对终端、SSH 和开发者都足够友好。它并不是从零实现的渲染引擎而是在 blessed 提供的窗口、文本、列表等基础组件之上扩展出一系列自定义 Widget底层画布Canvas能力来自drawille-canvas-blessed-contribdrawille 的衍生实现用于在字符网格上绘制连续曲线与图形地图组件依赖map-canvasMarkdown 渲染依赖marked与marked-terminal图片显示依赖picture-tuber这些依赖均可在 package.json 的dependencies中确认。从 入口文件 可以看到库对外统一导出了grid、carousel两个布局map、canvas、gauge、gaugeList、lcd、donut、log、picture、sparkline、table、tree、markdown等 Widget以及bar、stackedBar、line三个图表组件还有一组面向服务端场景的OutputBuffer、InputBuffer、createScreen、serverError工具见 lib/server-utils.js。安装与运行 Demo克隆并运行自带示例git clone https://github.com/yaronn/blessed-contrib.git cd blessed-contrib npm install node ./examples/dashboard.js其中examples/dashboard.js是官方自带的富仪表盘示例其演示效果如下完整动图见 docs/images/term3.gif该库支持 Linux、OS X 与 WindowsWindows 上需要先满足 blessed 的相关前置条件如正确的终端与编码环境。在自定义项目中使用如果要在自己的项目中构建仪表盘只需安装两个包npm install blessed blessed-contrib通用使用模式Screen、Widget 与 setData 生命周期blessed-contrib 的所有 Widget 遵循同一套使用模式README 给出的折线图最小示例完整展示了一次生命周期var blessed require(blessed) , contrib require(blessed-contrib) , screen blessed.screen() , line contrib.line( { style: { line: yellow , text: green , baseline: black} , xLabelPadding: 3 , xPadding: 5 , label: Title}) , data { x: [t1, t2, t3, t4], y: [5, 1, 7, 5] } screen.append(line) // 必须在设置数据前 append line.setData([data]) screen.key([escape, q, C-c], function(ch, key) { return process.exit(0); }); screen.render()这里有几个必须遵守的关键约定先screen.append(widget)再widget.setData(data)所有基于画布的 Widget 在attach挂载到 screen事件中才会初始化画布上下文this.ctx。从 lib/widget/charts/line.js 的setData实现可见若ctx不存在会直接抛出错误error: canvas context does not exist. setData() for line charts must be called after the chart has been added to the screen via screen.append()。Bar、Donut、Gauge 等组件都有同样的校验逻辑。所有组件都是 blessed 的Node/Box子类以 lib/widget/canvas.js 为例Canvas继承自blessed.Box在attach时通过drawille-canvas-blessed-contrib的Canvas创建内部画布并取出 2D 上下文ctxrender()时把画布帧frame()写入组件内容再交给 blessed 渲染。最后由screen.render()统一刷新并注册退出快捷键escape、q、C-c。除了 README 提到的 blessed 原生组件文本、列表等blessed-contrib 提供的 Widget 完整清单如下Line Chart、Bar Chart、Stacked Bar Chart、Map、Gauge、Stacked Gauge、Donut、LCD Display、Rolling Log、Picture、Sparkline、Table、Tree、Markdown。Widget 详解配置参数与数据格式Line Chart折线图var line contrib.line( { style: { line: yellow , text: green , baseline: black} , xLabelPadding: 3 , xPadding: 5 , showLegend: true , wholeNumbersOnly: false // trueY 轴不显示小数 , label: Title}) var series1 { title: apples, x: [t1, t2, t3, t4], y: [5, 1, 7, 5] } var series2 { title: oranges, x: [t1, t2, t3, t4], y: [2, 1, 4, 8] } screen.append(line) // 必须在设置数据前 append line.setData([series1, series2])setData接收一个系列数组每个系列含title、x横轴标签数组、y数值数组并可选style.line单独指定该系列颜色。从 lib/widget/charts/line.js 的默认参数可知style.line默认yellowstyle.text默认greenstyle.baseline默认blackxLabelPadding默认 5、xPadding默认 10、numYLabels默认 5Y 轴标签数量wholeNumbersOnly默认false为true时 Y 轴刻度取整不显示小数minY默认 0可抬升 Y 轴起点maxY可显式指定上限showLegend为true时自动绘制图例图例宽度可通过legend.width调整默认 15。从实现看图例是动态append到组件上的一个blessed.box见 lib/widget/charts/line.js#L53-L84每条线使用utils.getColorCode将颜色名转换为对应的 ANSI 前景色代码。此外 README 还提供了三个可直接运行的示例简单折线图、多系列折线、256 色折线。Bar Chart柱状图var bar contrib.bar( { label: Server Utilization (%) , barWidth: 4 , barSpacing: 6 , xOffset: 0 , maxHeight: 9}) screen.append(bar) // 必须在设置数据前 append bar.setData( { titles: [bar1, bar2] , data: [5, 10]})柱状图内部使用ansi-term画布见 lib/widget/charts/bar.js。从源码可确认其默认值与行为barWidth默认 6barSpacing默认 9若barSpacing - barWidth 3会自动把barSpacing调整为barWidth 3保证柱子间至少有 3 个字符的间距xOffset默认 5控制第一根柱子的起始偏移showText默认为true控制是否在柱体上/下方绘制数值与标题数据为 0 时柱子不填充颜色额外支持barBgColor柱体颜色、barFgColor数值文字颜色、labelColor标题颜色maxHeight用于约束柱高的比例基准。Stacked Bar Chart堆叠柱状图bar contrib.stackedBar( { label: Server Utilization (%) , barWidth: 4 , barSpacing: 6 , xOffset: 0 //, maxValue: 15 , height: 40% , width: 50% , barBgColor: [ red, blue, green ]}) screen.append(bar) bar.setData( { barCategory: [Q1, Q2, Q3, Q4] , stackedCategory: [US, EU, AP] , data: [ [ 7, 7, 5] , [8, 2, 0] , [0, 0, 0] , [2, 3, 2] ] })堆叠柱状图的数据结构是三层嵌套barCategory是横轴分组每个分组一根柱子stackedCategory是堆叠层的名称data是一个二维数组data[i][j]表示第i根柱子中第j个堆叠层的数值。barBgColor传入颜色数组分别对应每一层的颜色maxValue可显式指定纵轴最大值默认由数据自动计算。示例可参考 examples/stacked-bar.js。Map地图var map contrib.map({label: World Map}) map.addMarker({lon : -79.0000, lat : 37.5000, color: red, char: X })Map Widget 渲染世界地图底图addMarker通过经纬度lon/lat在地图上打点可指定color与char标记字符。完整示例见 examples/map.js。Gauge仪表盘var gauge contrib.gauge({label: Progress, stroke: green, fill: white}) gauge.setPercent(25)从 lib/widget/gauge.js 可知stroke默认magenta进度条颜色、fill默认white文字颜色、showLabel默认true显示百分比文本。setPercent接受 0~100 或 0~1 两种数值从源码看若percent 1.001会自动乘以 100 转换为百分比见 lib/widget/gauge.js#L61-L63。组件也兼容在构造时通过percent或stack选项直接初始化。Stacked Gauge堆叠仪表盘堆叠仪表盘有两种写法。第一种是每个分段显式指定百分比与颜色var gauge contrib.gauge({label: Stacked }) gauge.setStack([{percent: 30, stroke: green}, {percent: 30, stroke: magenta}, {percent: 40, stroke: cyan}])第二种是只传数值数组颜色会自动从内置色板[green,magenta,cyan,red,blue]中轮询选取见 lib/widget/gauge.js#L76var gauge contrib.gauge({label: Stacked Progress}) gauge.setStack([30,30,40])注意 README 中的示例直接使用contrib.gauge(...)构造并调用setStack与setData传入数组时的内部行为一致——setData会智能分派传入数组走setStack传入数字走setPercent见 lib/widget/gauge.js#L41-L47。相关示例见 examples/gauge-stack.js 与 examples/gauge-list.js。Donut环形图var donut contrib.donut({ label: Test, radius: 8, arcWidth: 3, remainColor: black, yPadding: 2, data: [ {percent: 80, label: web1, color: green} ] });Donut 数据中的每一项使用percent百分比与label标签绘制环形color可选、默认绿色。更新数据同样简单把相同格式的数组传给setData即可donut.setData([ {percent: 87, label: rcp,color: green}, {percent: 43, label: rcp,color: cyan}, ]);传入多少个数据项都可以它们会自动缩放并尝试排布但实际仍受屏幕空间限制。从 lib/widget/donut.js 可确认默认参数stroke默认magenta、fill默认white、radius默认 14、arcWidth默认 4、spacing默认 2、yPadding默认 2、remainColor默认black未填充的剩余环形颜色。另外percent也可传入 0~1 的小数实现中会自动换算见 lib/widget/donut.js#L108-L111。你还可以通过percentAltNumber属性在环形中心显示一个自定义数字替代默认的百分比文本var donut contrib.donut({ label: Test, radius: 8, arcWidth: 3, remainColor: black, yPadding: 2, data: [ {percentAltNumber: 50, percent: 80, label: web1, color: green} ] });此用法可参考 examples/donut.js 中的某个 donut 配置。LCD DisplayLCD 数码管显示var lcd contrib.lcd( { segmentWidth: 0.06 // 段宽百分比表示50% 即 0.5 , segmentInterval: 0.11 // 段与段之间的间距百分比 , strokeWidth: 0.11 // 笔画宽度百分比 , elements: 4 // 显示的元素个数即可显示的字符数 , display: 321 // 首次调用 setDisplay 前显示的内容 , elementSpacing: 4 // 每个元素之间的间距 , elementPadding: 2 // 元素距边缘的距离 , color: white // 段的颜色 , label: Storage Remaining})lcd.setDisplay(23 G); // 将显示 23G lcd.setOptions({}) // 运行时调整选项LCD 使用十六段SixteenSegment字形模拟数码管。从 lib/widget/lcd.js 可以看到默认值segmentWidth默认 0.06、segmentInterval默认 0.11、strokeWidth默认 0.11、elements默认 3、display默认 321、elementSpacing默认 4、elementPadding默认 2、color默认white。请参考 examples/lcd.js 的示例它提供了按键绑定可在运行时实时调整segmentWidth、segmentInterval与strokeWidth直观观察这三个参数对显示效果的影响对应源码中的increaseWidth/decreaseWidth/increaseInterval等方法见 lib/widget/lcd.js#L49-L60。Rolling Log滚动日志var log contrib.log( { fg: green , selectedFg: green , label: Server Log}) log.log(new log line)Log Widget 适合展示持续追加的日志流通过log()方法逐行写入fg与selectedFg分别控制文本与选中行颜色。完整示例见 examples/log.js。Picture图片显示var pic contrib.picture( { file: ./flower.png , cols: 25 , onReady: ready}) function ready() {screen.render()}Picture Widget 把 PNG 图片按 ANSI 色块渲染到终端仅支持 PNG 格式。由于图片解码是异步的需要通过onReady回调触发screen.render()来刷新画面cols控制渲染宽度示例图片见 examples/media/flower.png。注意 README 同时指出新的 blessed image 实现blessed.image从 Box 派生在某些方面优于本组件可酌情选用。Sparkline迷你趋势图var spark contrib.sparkline( { label: Throughput (bits/sec) , tags: true , style: { fg: blue }}) sparkline.setData( [ Sparkline1, Sparkline2], [ [10, 20, 30, 20] , [40, 10, 40, 50]])setData接收两个数组第一个是每条趋势线的名称列表第二个是对应的数值序列二维数组style.fg设置文字颜色tags启用 blessed 的标签语法着色。示例见 examples/sparkline.js。Table表格var table contrib.table( { keys: true , fg: white , selectedFg: white , selectedBg: blue , interactive: true , label: Active Processes , width: 30% , height: 30% , border: {type: line, fg: cyan} , columnSpacing: 10 // 单位字符 , columnWidth: [16, 12, 12] /* 单位字符 */ }) // 允许用键盘控制表格 table.focus() table.setData( { headers: [col1, col2, col3] , data: [ [1, 2, 3] , [4, 5, 6] ]})Table 支持interactive: true开启交互选择selectedFg/selectedBg控制选中行配色columnSpacing与columnWidth数组分别指定每列宽度控制列布局。调用table.focus()后将键盘焦点交给表格可用方向键浏览行。更多示例见 examples/table.js 与 examples/table-color.js。Tree树形控件var tree contrib.tree({fg: green}) // 允许用键盘控制树 tree.focus() tree.on(select,function(node){ if (node.myCustomProperty){ console.log(node.myCustomProperty); } console.log(node.name); }) // 可以在根级别指定 name 属性来显示根节点 tree.setData( { extended: true , children: { Fruit: { children: { Banana: {} , Apple: {} , Cherry: {} , Exotics: { children: { Mango: {} , Papaya: {} , Kiwi: { name: Kiwi (not the bird!), myCustomProperty: hairy fruit } }} , Pear: {}}} , Vegetables: { children: { Peas: {} , Lettuce: {} , Pepper: {}}}}})Tree 通过setData传入嵌套的节点哈希并通过select事件回调获得当前选中节点。完整示例见 examples/explorer.js文件浏览器该示例演示了用函数动态生成子节点。Tree 的 Options选项说明默认值keys展开节点的按键[enter,default]extended节点默认是否展开/生成子节点。使用回调函数生成子节点时请谨慎设置falsetemplate.extend折叠节点的前缀图标[]template.retract展开节点的前缀图标[-]template.lines是否显示树形连线trueTree 的节点特殊属性每个节点都是一个哈希对象可以携带任意自定义属性并在select事件回调中使用同时存在几个特殊键属性类型说明namestring节点名称。非根节点未指定时取哈希键名如{ name: Fruit}childrenhash或function(node){ return children }节点的子节点。函数必须返回一个可作为 children 的哈希使用函数时结果会存入node.childrenContent与children。函数形式见 examples/explorer.jschildrenContenthash内部使用的子节点内容不要修改。若node.children是哈希则node.children node.childrenContent若是函数则用于缓存node.children()的返回结果。通常可在自定义children函数中用if(node.childrenContent)判断是否只生成一次子节点extendedboolean该节点是否展开。无子节点时无效节点未设置时取treeInstance.options.extended。示例{Fruit:{ name: Fruit, extended: true, children:{...}}}MarkdownMarkdown 渲染var markdown contrib.markdown() markdown.setMarkdown(# Hello \n blessed-contrib renders markdown using marked-terminal)Markdown Widget 通过marked-terminal在终端内渲染 Markdown 内容setMarkdown传入原始 Markdown 字符串即可。示例见 examples/markdown.js 与 examples/marked-terminal.js。颜色系统支持 256 色blessed-contrib 的颜色选项可以直接使用 256 色 RGB 数组而不仅限于预设颜色名。README 给出的示例如下function randomColor() { return [Math.random() * 255,Math.random()*255, Math.random()*255] } line contrib.line( { ... , style: { line: randomColor(), text: randomColor(), baseline: randomColor() } })颜色值经过utils.getColorCode转换后写入画布上下文见 lib/widget/charts/line.js#L79。这一机制依赖x256依赖将 RGB 映射为 xterm 256 色索引。完整示例见 examples/line-random-colors.js可以运行它直观观察随机配色效果。布局系统Grid 与 CarouselGrid网格布局Grid 自动将 Widget 摆放到网格单元中。使用 Grid 时不应自行创建 Widget而是把要创建的组件类型与参数交给 Grid由它实例化并append到 screen。每个 Widget 可以跨多行多列var screen blessed.screen() var grid new contrib.grid({rows: 12, cols: 12, screen: screen}) //grid.set(row, col, rowSpan, colSpan, obj, opts) var map grid.set(0, 0, 4, 4, contrib.map, {label: World Map}) var box grid.set(4, 4, 4, 4, blessed.box, {content: My Box}) screen.render()grid.set(row, col, rowSpan, colSpan, obj, opts)的参数含义为起始行、起始列、跨行数、跨列数、组件构造器、组件选项。从 lib/layout/grid.js 的源码可以了解其内部机制构造时必须提供screen否则抛出异常dashboardMargin默认 0用于在网格四周留白单元尺寸按百分比计算cellWidth (100 - margin*2) / colscellHeight (100 - margin*2) / rowsset会基于行列与跨幅算出top、left、width、height均为百分比字符串并默认给每个组件加上border: {type: line, fg: cyan}边框可通过hideBorder关闭边框颜色由color选项指定然后调用obj(options)创建实例并screen.append最后返回该实例Grid 不允许嵌套对嵌套传入 Grid 会抛出异常。示例见 examples/grid.js 与 examples/grid-no-border.js。Carousel轮播布局Carousel 布局根据时间或键盘操作在多个页面之间切换典型场景是办公室大屏的轮播仪表盘var blessed require(blessed) , contrib require(./) , screen blessed.screen() function page1(screen) { var map contrib.map() screen.append(map) } function page2(screen) { var line contrib.line( { width: 80 , height: 30 , left: 15 , top: 12 , xPadding: 5 , label: Title }) var data [ { title: us-east, x: [t1, t2, t3, t4], y: [0, 0.0695652173913043, 0.11304347826087, 2], style: { line: red } } ] screen.append(line) line.setData(data) } screen.key([escape, q, C-c], function(ch, key) { return process.exit(0); }); var carousel new contrib.carousel( [page1, page2] , { screen: screen , interval: 3000 // 每隔多少毫秒自动切换视图设为 0 则永不自动切换 , controlKeys: true // 是否允许左右方向键控制视图轮转 }) carousel.start()从 lib/layout/carousel.js 的实现可以看到start()首先渲染第一页若设置了interval则通过setInterval定时调用next()若controlKeys为true则注册right、left、home、end四个方向键分别对应下一页、上一页、回到首页、跳到末页。每一页就是接收screen参数的普通函数切换时 Carousel 会清空 screen 上所有子组件并调用当前页函数重新布局。rotate选项控制到达末尾后是否回绕到首页。从零搭建一个简单仪表盘README 给出了一个可直接运行的组合示例用 Grid 把折线图股票走势与世界地图服务器位置拼成双面板仪表盘var blessed require(blessed) , contrib require(blessed-contrib) , screen blessed.screen() , grid new contrib.grid({rows: 1, cols: 2, screen: screen}) var line grid.set(0, 0, 1, 1, contrib.line, { style: { line: yellow , text: green , baseline: black} , xLabelPadding: 3 , xPadding: 5 , label: Stocks}) var map grid.set(0, 1, 1, 1, contrib.map, {label: Servers Location}) var lineData { x: [t1, t2, t3, t4], y: [5, 1, 7, 5] } line.setData([lineData]) screen.key([escape, q, C-c], function(ch, key) { return process.exit(0); }); screen.render()更丰富的仪表盘多 Widget、随机数据轮询等可直接查看 examples/dashboard.js 的源码其运行效果见上文 Demo 动图docs/images/term3.gif故障排查乱码与字符缺失如果终端中出现问号或部分乃至全部字符缺失通常是字符编码或终端类型设置不正确。README 建议以如下环境变量启动脚本强制使用 UTF-8 与 256 色终端$ LANGen_US.utf8 TERMxterm-256color node your-code.js相关资源与扩展阅读示例集examples/目录下为每个 Widget 都提供了可运行示例inline-data/子目录还有不依赖真实数据源的最小化版本是学习参数与数据格式的最佳入口。TypeScript 支持仓库提供了 index.d.ts 类型声明package.json的types字段已指向它TypeScript 项目可直接获得类型提示。WOPR 标记语言README 还推荐了同作者的另一项目 WOPR——一种用于创建终端报表、演示文稿与信息图的标记语言可作为 blessed-contrib 的补充方案。许可证本项目基于 MIT License 开源详见 LICENSE.md。综上blessed-contrib 以“blessed 组件体系 drawille 字符画布”为底座通过一套统一的contrib.xxx(options)构造、screen.append()挂载、xxx.setData()喂数据的 API 约定把 14 种图表与信息组件带进了任何支持 ANSI 的终端。无论是 SSH 远程监控、办公室轮播大屏还是运维自研的轻量面板都可以用它快速落地动手从 examples/dashboard.js 开始改造是上手最快的路径。赞分享前端UI组件数据可视化【免费下载链接】blessed-contribBuild terminal dashboards using ascii/ansi art and javascript项目地址https://gitcode.com/gh_mirrors/bl/blessed-contrib点击查看免费下载相关推荐开源神器blessed-contrib - 超级终端仪表盘构建器开源神器blessed contrib 超级终端仪表盘构建器 项目介绍 在编程的世界里数据可视化往往能够帮助我们更直观地理解复杂的信息。 blessed c前端UI组件数据可视化blessed-contrib构建终端仪表板的终极指南blessed contrib构建终端仪表板的终极指南 blessed contrib是一个基于Node.js的终端仪表板库通过ASCII/ANSI艺术与J前端UI组件数据可视化从 10 分钟音频到专属音色RVC WebUI 完整上手指南从 10 分钟音频到专属音色RVC WebUI 完整上手指南 你有没有想过能不能只录一小段话就让 AI 用「另一个人的嗓音」说出你的内容 比如想把一首歌人工智能AI 应用语音音频深度学习上一篇SensorsCalibration在自动驾驶系统中的应用传感器融合与定位精度的提升下一篇Qwen3-4B模型架构解密MindSpore框架下的大语言模型创新设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考