ThingsBoard 自定义 Time-Series 时序表格部件开发:Widget Editor 完整实战与订阅数据模型源码解析
物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载本文以 ThingsBoard 前端仓库ui-ngx内置的官方示例 timeseries_widget.md 为核心手把手讲解如何在Widgets Bundle 视图中从零创建一个自定义Time-Series 时序部件通过 HTML/CSS/JavaScript 三个代码区实现每个数据源一个页签、页签内以表格展示最新时序数据的效果并深入解析部件subscription订阅对象与defaultSubscription的数据结构帮助读者掌握 ThingsBoard 自定义部件的完整开发与调试能力。一、前置认知Widget Editor 与 Time-Series 部件类型ThingsBoard 的自定义部件开发都在Widget Editor部件编辑器中完成它允许开发者用 HTML、CSS、JavaScriptAngular 模板语法定义部件的外观与行为。部件类型决定订阅的数据结构Latest values最新值与Time-Series时序部件订阅对象提供datasources数据源数组与data最新/时序数据数组Alarm告警部件提供alarmSource与alarmsRPC / Static部件订阅对象可选通常不包含必要的数据信息。官方对部件生命周期函数与订阅对象的完整说明见 widget_js_fn.md 与 widget_js_subscription_object.md。本示例聚焦Time-Series类型其最终效果为多个数据源以mat-tab页签切换每个页签内渲染一张时间戳 各数据键dataKey数值的表格。二、创建步骤从 Widgets Bundle 进入 Time-Series 模板打开Widgets Bundle部件库视图点击屏幕右下角的大按钮在弹出的菜单中点击Create new widget type创建新部件类型在Select widget type选择部件类型弹窗中点击Time-Series按钮Widget Editor随即打开并自动填充默认的Time-Series模板部件内容此时Resources区已包含 CSS、HTML 两个标签页JavaScript区已包含默认部件骨架代码。接下来只需分别替换三处代码并点击Run即可看到运行结果。三、替换 CSS定义表格表头左对齐样式将 Resources 区CSS标签页的内容替换为.my-data-table th { text-align: left; }该样式为示例表格定义了my-data-table类使表头th文本左对齐避免默认居中样式影响阅读。四、替换 HTML以页签 表格渲染多数据源时序数据将 Resources 区HTML标签页的内容替换为mat-tab-group styleheight: 100%; mat-tab *ngForlet datasource of datasources; let $dsIndex index label{{datasource.name}} table classmy-data-table stylewidth: 100%; thead tr thTimestamp/th th *ngForlet dataKeyData of datasourceData[$dsIndex]{{dataKeyData.dataKey.label}}/th tr /thead tbody tr *ngForlet data of datasourceData[$dsIndex][0].data; let $dataIndex index td{{data[0] | date : yyyy-MM-dd HH:mm:ss}}/td td *ngForlet dataKeyData of datasourceData[$dsIndex]{{dataKeyData.data[$dataIndex] dataKeyData.data[$dataIndex][1]}}/td /tr /tbody /table /mat-tab /mat-tab-group该模板使用 Angular 结构型指令*ngFor官方参考 Angular NgForOf API外层*ngForlet datasource of datasources; let $dsIndex index遍历当前订阅的所有数据源为每个数据源渲染一个mat-tab页签页签标题为datasource.name表头*ngForlet dataKeyData of datasourceData[$dsIndex]按数据源索引读取$scope.datasourceData将每个dataKeyData的dataKey.label渲染为列标题首列固定为 Timestamp表体*ngForlet data of datasourceData[$dsIndex][0].data以第一个 dataKey 的data数组为行基准data[0]为毫秒级 Unix 时间戳通过 Angulardate管道格式化为yyyy-MM-dd HH:mm:ssdataKeyData.data[$dataIndex][1]为对应时间点的数值最后一行使用Angular 表达式求值短路A B当某 dataKey 在对应索引处无数据点时返回空避免渲染undefined。五、替换 JavaScript初始化订阅数据并响应数据更新将JavaScript区的内容替换为self.onInit function() { self.ctx.widgetTitle My first Time-Series widget; self.ctx.$scope.datasources self.ctx.defaultSubscription.datasources; self.ctx.$scope.data self.ctx.defaultSubscription.data; self.ctx.$scope.datasourceData []; var currentDatasource null; var currentDatasourceIndex -1; for (var i0;iself.ctx.$scope.data.length;i) { var dataKeyData self.ctx.$scope.data[i]; if (dataKeyData.datasource ! currentDatasource) { currentDatasource dataKeyData.datasource currentDatasourceIndex; self.ctx.$scope.datasourceData[currentDatasourceIndex] []; } self.ctx.$scope.datasourceData[currentDatasourceIndex].push(dataKeyData); } self.ctx.updateWidgetParams(); } self.onDataUpdated function() { self.ctx.detectChanges(); }代码要点self是部件实例的内置引用每个部件函数都应定义为self的属性详见 widget_js_fn.mdself.ctx是 WidgetContext 类型引用提供部件所需的全部 API 与数据onInit在部件初始化时调用将defaultSubscription.datasources数据源数组与defaultSubscription.data各 dataKey 的时序数据数组挂载到$scope使其在 HTML 模板中可直接访问$scope.datasourceData是本示例引入的关键重组结构由于data是按datasourcedataKey平铺的见下文订阅结构这里遍历data每当dataKeyData.datasource发生变化就开启一个新的数据源索引把属于同一数据源的所有dataKeyData收集到datasourceData[索引]数组中——HTML 中便可以通过datasourceData[$dsIndex]按数据源索引灵活取用updateWidgetParams()同步部件参数底层实现见下节源码解析onDataUpdated在订阅收到新数据时被调用这里仅执行detectChanges()触发一次新的 Angular 变更检测使表格中的数据及时刷新。六、运行与预览完成上述替换后点击Widget Editor Toolbar上的Run按钮即可在Widget preview部件预览区看到运行结果预览中可以看到每个数据源对应一个页签表格首列展示格式化的时间戳其余列按 dataKey 的 label 展示各数据键的数值。七、源码级解析subscription 订阅对象与 defaultSubscription示例中的核心数据来源是self.ctx.defaultSubscription它是 IWidgetSubscription 的实例源码定义于 widget-api.models.ts包含该订阅的全部信息与当前数据。在 widget-component.models.ts 中WidgetContext声明了defaultSubscription: IWidgetSubscription null部件代码中可随时读取。7.1 datasources数据源数组datasources [ { // datasource type: entity,// type of the datasource. Can be function or entity name: name, // name of the datasource (in case of entity usually Entity name) aliasName: aliasName, // name of the alias used to resolve this particular datasource Entity entityName: entityName, // name of the Entity used as datasource entityType: DEVICE, // datasource Entity type (for ex. DEVICE, ASSET, TENANT, etc.) entityId: 943b8cd0-576a-11e7-824c-0b1cb331ec92, // entity identificator presented as string uuid. dataKeys: [ // array of keys (attributes or timeseries) of the entity used to fetch data { // dataKey name: name, // the name of the particular entity attribute/timeseries type: timeseries, // type of the dataKey. Can be timeseries, attribute or function label: Sin, // label of the dataKey. Used as display value (for ex. in the widget legend section) color: #ffffff, // color of the key. Can be used by widget to set color of the key data. funcBody: , // only applicable for datasource with type function and function key type. settings: {} // dataKey specific settings with structure according to the defined Data key settings form. }, //... ] }, //... ]type为function时代表模拟数据源配合funcBody生成仿真数据为entity时代表真实实体数据源aliasName指向仪表板中配置的实体别名。7.2 data各 dataKey 的时序数据点data [ { datasource: {}, // datasource object of this data. See datasource structure above. dataKey: {}, // dataKey for which the data is held. See dataKey structure above. data: [ // array of data points [ // data point 1498150092317, // unix timestamp of datapoint in milliseconds 1, // value, can be either string, numeric or boolean ], //... ] }, //... ]data的每个元素DatasourceData对应一个数据源 一个 dataKey的组合数据点以[时间戳, 数值]二元数组表示。这也解释了示例 JavaScript 为什么要按dataKeyData.datasource归组data是平铺结构而 HTML 表格需要按数据源聚合datasourceData正是为这种按数据源索引访问而引入的重组视图。7.3 IWidgetSubscription 接口中的相关成员在 IWidgetSubscription 接口中可看到与示例直接对应的成员datasources?: ArrayDatasource—— 订阅使用的数据源数组data?: ArrayDatasourceData—— 订阅范围内收到的数据latestData?: ArrayDatasourceData—— 最新值数据Latest values 部件使用type: widgetType、callbacks: WidgetSubscriptionCallbacks等成员共同支撑订阅的生命周期与回调如onDataUpdated对应接口中的WidgetSubscriptionCallbacks.onDataUpdated。7.4 WidgetContext 的 detectChanges 与 updateWidgetParams 底层实现示例中调用的两个 API 在 widget-component.models.ts 中有明确实现detectChanges()在ngZone内调用changeDetectorValue?.detectChanges()触发 Angular 变更检测带updateWidgetParams可选参数为true时先同步部件参数。这正是示例注释中所说的收到新数据时必须执行新的变更检测周期的底层原因updateWidgetParams()通过setTimeout(..., 0)异步调用dashboardWidget.updateWidgetParams()同步部件参数。八、调试技巧与扩展方向官方文档 widget_js_fn.md 还给出了部件代码的两类调试方法Web 控制台输出在部件 JavaScript 任意位置放置console.log(...)点击Run重启部件代码在浏览器控制台观察输出浏览器调试器在感兴趣的位置放置debugger;语句并点击Run浏览器会自动在断点处暂停可用调试工具逐步分析执行过程。基于本示例的datasourceData重组模式可以进一步扩展把data[0]的毫秒时间戳配合date管道展示更丰富的日期格式参照 latest_values_widget.md 使用latestData实现最新值部件为表格列标题绑定dataKey.color实现图例着色借鉴 widget_js_fn.md 中onResize、onDestroy、getSettingsForm、typeParameters、actionSources等生命周期函数为部件增加设置表单与用户动作。至此一个可运行的多数据源 Time-Series 表格部件已完成创建。整个示例的全部代码与说明均可在仓库 ui-ngx/src/assets/help/en_US/widget/editor/examples/timeseries_widget.md 中查看与复现。赞分享物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载相关推荐Neon 怎么把 Postgres 上游小版本合并进 neon postgres 并更新仓库引用Neon 怎么把 Postgres 上游小版本合并进 neon postgres 并更新仓库引用 Neon 把 Postgres 以 forkneondata物联网后端数据可视化消息队列ThingsBoard Alarm Widget 从零到实战基于 Widget Editor 开发自定义告警表格组件ThingsBoard Alarm Widget 从零到实战基于 Widget Editor 开发自定义告警表格组件 本指南以 ThingsBoard 官方示物联网后端数据可视化消息队列ThingsBoard 静态 Widget 开发实战从 Widget Editor 创建无数据源的自定义 UI 组件ThingsBoard 静态 Widget 开发实战从 Widget Editor 创建无数据源的自定义 UI 组件 导读 静态 WidgetStatic物联网后端数据可视化消息队列上一篇终极指南如何使用WandEnhancer免费解锁WeMod高级功能下一篇ColorControl高性能跨设备显示控制与智能协同系统深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

微服务日志聚合模式(Microservices Log Aggregation)在 Java 中的实现与实战指南

微服务日志聚合模式(Microservices Log Aggregation)在 Java 中的实现与实战指南

示例工程教程 【免费下载链接】java-design-patterns Design patterns implemented in Java 项目地址: https://gitcode.com/GitHub_Trending/ja/java-design-patterns 点击查看 免费下载 本文基于 java-design-patterns 仓库中的 microservices-log-aggregation 模…

2026/10/4 20:27:33 阅读更多 →
docker-selenium 4.48.0 版本矩阵解读:Chrome 106 镜像标签的生成、命名与拉取实战

docker-selenium 4.48.0 版本矩阵解读:Chrome 106 镜像标签的生成、命名与拉取实战

测试后端云原生容器编排可观测性 【免费下载链接】docker-selenium Provides a simple way to run Selenium Grid with Chrome, Firefox, and Edge using Container Platform, making it easier to perform browser automation at scale 项目地址: https://gitcode.…

2026/10/3 20:26:26 阅读更多 →
Go 语言技能评估全解析:linkedin-skill-assessments-quizzes 仓库 Go 题库深度解读

Go 语言技能评估全解析:linkedin-skill-assessments-quizzes 仓库 Go 题库深度解读

文档教程知识库教育 【免费下载链接】linkedin-skill-assessments-quizzes Full reference of LinkedIn answers 2024 for skill assessments (aws-lambda, rest-api, javascript, react, git, html, jquery, mongodb, java, Go, python, machine-learning, power-point) linke…

2026/10/3 20:26:26 阅读更多 →

最新新闻

业务系统快速接入阿里云短信API,实现会员到期提醒全攻略

业务系统快速接入阿里云短信API,实现会员到期提醒全攻略

我们系统之前一直用邮件做会员到期提醒,效果实在一般,打开率低不说,还经常被扔进垃圾箱。后来换成短信提醒接口,触达效率完全不一样。这个事我在业务系统里从零到一对接过好几轮:设计方案、申请签名模板、写发送代码、…

2026/10/5 2:54:48 阅读更多 →
CNN-BiLSTM中文情感分析:毕设源码实战与调参避坑指南

CNN-BiLSTM中文情感分析:毕设源码实战与调参避坑指南

简介:这是一套面向计算机相关专业学生与项目实战学习者的中文情感分析系统源码,采用CNN-Bi-LSTM混合神经网络实现,适合作为毕业设计、课程设计或期末大作业的参考方案。资源包共35个文件,以13个Python源码文件为核心,涵…

2026/10/5 2:54:47 阅读更多 →
国产化系统落地多语言文本分类:libexttextcat离线部署实践

国产化系统落地多语言文本分类:libexttextcat离线部署实践

做多语言文本处理的人,大概都绕不开同一个问题:一段文本丢进来,到底是中文、英文、法语,还是斯拉夫语系的某一种?很多团队上来就选fastText或者调大模型接口,但在国产化服务器、内网隔离、数据不出域的约束…

2026/10/5 2:54:47 阅读更多 →
2026年网络安全入行指南:技术方向、实战建议与就业真相

2026年网络安全入行指南:技术方向、实战建议与就业真相

这两年问我“网络安全还能不能入行”的人,比问我“哪个漏洞平台好挖”的还多。大家的心态我能理解:一边是新闻里不断出现的攻击事件,一边是网上铺天盖地的“裁员”“饱和”“卷不动”论调,2026年这个节点上,网络安全到…

2026/10/5 2:54:47 阅读更多 →
基于Python卷积神经网络的人脸识别驾驶员疲劳检测与预警系统实战

基于Python卷积神经网络的人脸识别驾驶员疲劳检测与预警系统实战

简介:这份毕业设计资源面向计算机相关专业学生与Python初学者,提供一套基于卷积神经网络的人脸识别驾驶员疲劳检测与预警系统完整源码,可用于课程设计、毕设答辩或深度学习入门实践。压缩包共15个文件,约2.8MB,包含3个…

2026/10/5 2:54:47 阅读更多 →
职校管理总是“差点意思“,学工管理系统升级到底能不能破解这些痛点?

职校管理总是“差点意思“,学工管理系统升级到底能不能破解这些痛点?

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

2026/10/5 2:53:47 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

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

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

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

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/4 11:40:45 阅读更多 →
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/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练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/4 20:14:29 阅读更多 →