当前位置: 首页 > news >正文

avalonia、WPF使用ScottPlot动态显示ECG心电图

文章目录

    • avalonia、WPF使用ScottPlot动态显示ECG心电图
    • 实现效果,动态效果懒得录视频了
    • 安装
    • 代码部分
    • UpdateData方法就是用来更新心电图表的方法, 根据消息队列数据去更新是视图中的ScottPlot 图表

avalonia、WPF使用ScottPlot动态显示ECG心电图

avalonia、WPF使用ScottPlot动态显示ECG心电图

实现效果,动态效果懒得录视频了

请添加图片描述

安装

1.安装ScottPlot.Avalonia NuGet包

注意:
如果开发环境是macos、linux,需要按照官网步骤配置环境
此处是官网配置链接

代码部分

view部分 注意安装包之后引入
xmlns:ScottPlot="clr-namespace:ScottPlot.Avalonia;assembly=ScottPlot.Avalonia"

<Window xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d" d:DesignWidth="1920" d:DesignHeight="600"xmlns:vm="using:AvaloniaMedical.ViewModels"x:Class="AvaloniaMedical.Views.xx"xmlns:ScottPlot="clr-namespace:ScottPlot.Avalonia;assembly=ScottPlot.Avalonia"x:DataType="vm:xx"xmlns:views="clr-namespace:AvaloniaMedical.Views"xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"xmlns:controls1="clr-namespace:Material.Styles.Controls;assembly=Material.Styles"Background="#31363A">此处只显示三导心电<ScottPlot:AvaPlot Height="200"  Name="AvaPlotName1" Grid.Row="1" Grid.Column="0" ></ScottPlot:AvaPlot><ScottPlot:AvaPlot Height="200"  Name="AvaPlotName2" Grid.Row="2" Grid.Column="0" ></ScottPlot:AvaPlot><ScottPlot:AvaPlot Height="200" Name="AvaPlotName3" Grid.Row="3" Grid.Column="0" ></ScottPlot:AvaPlot>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using AvaloniaMedical.ViewModels;
using Npoi.Mapper;
using ScottPlot;
using ScottPlot.Avalonia;
using ScottPlot.Plottable;namespace AvaloniaMedical.Views;public partial class xx : Window
{private readonly double[] liveData = new double[4000];private readonly double[] liveData2 = new double[4000];private readonly double[] liveData3 = new double[4000];private readonly Timer _updateDataTimer;private readonly DispatcherTimer _renderTimer;private readonly VLine vline;private readonly VLine vline2;private readonly VLine vline3;int nextValueIndex = -1;int nextValueIndex2 = -1;int nextValueIndex3= -1;AvaPlot AvaPlot1;AvaPlot AvaPlot2;AvaPlot AvaPlot3;public xx(){InitializeComponent();#if DEBUGthis.AttachDevTools();
#endifAvaPlot1 = this.Find<AvaPlot>("AvaPlotName1");AvaPlot2 = this.Find<AvaPlot>("AvaPlotName2");AvaPlot3 = this.Find<AvaPlot>("AvaPlotName3");AvaPlot1.Plot.AddSignal(liveData, 1, color: Color.LightGreen);AvaPlot1.Plot.AxisAutoX(margin: 0);AvaPlot1.Plot.SetAxisLimits(yMin: 2, yMax:7);AvaPlot2.Plot.AddSignal(liveData2, 1, color: Color.LightGreen);AvaPlot2.Plot.AxisAutoX(margin: 0);AvaPlot2.Plot.SetAxisLimits(yMin: 2, yMax: 7);AvaPlot3.Plot.AddSignal(liveData3, 1, color: Color.LightGreen);AvaPlot3.Plot.AxisAutoX(margin: 0);AvaPlot3.Plot.SetAxisLimits(yMin: 2, yMax: 7);vline = AvaPlot1.Plot.AddVerticalLine(0, Color.LightGreen, 1);vline2 = AvaPlot2.Plot.AddVerticalLine(0, Color.LightGreen, 1);vline3 = AvaPlot3.Plot.AddVerticalLine(0, Color.LightGreen, 1);///Binding binding = new Binding();binding.Source = AvaPlot1;binding.Path = new ropertyPath();AvaPlot1.SetValue(TagProperty, 0);AvaPlot1.Plot.Style(Style.Gray1); AvaPlot2.Plot.Style(Style.Gray1); AvaPlot3.Plot.Style(Style.Gray1); customize styling//AvaPlot1.Plot.Title("Electrocardiogram Strip Chart");AvaPlot1.Plot.Grid(true);AvaPlot2.Plot.Grid(true);AvaPlot3.Plot.Grid(true);// create a traditional timer to update the data//_updateDataTimer = new Timer(_ => UpdateData(), null, 0, 1); create a separate timer to update the GUI_renderTimer = new DispatcherTimer{Interval = TimeSpan.FromMilliseconds(1)};_renderTimer.Tick += Render;_renderTimer.Start();Closed += (sender, args) =>{_updateDataTimer?.Dispose();_renderTimer?.Stop();};}public void UpdateChart(double dto){UpdateData(dto);}public void UpdateChart2(double dto){UpdateData2(dto);}public void UpdateChart3(double dto){UpdateData3(dto);}void UpdateData(double dto){// "scroll" the whole chart to the left// Array.Copy(liveData, 1, liveData, 0, liveData.Length - 1);// place the newest data point at the enddouble nextValue = dto;nextValueIndex = (nextValueIndex < liveData.Length - 1) ? nextValueIndex + 1 : 0;liveData[nextValueIndex] = nextValue;vline.IsVisible = true;vline.X = nextValueIndex;}void UpdateData2(double dto){// "scroll" the whole chart to the left// Array.Copy(liveData, 1, liveData, 0, liveData.Length - 1);// place the newest data point at the enddouble nextValue = dto;nextValueIndex2 = (nextValueIndex2 < liveData2.Length - 1) ? nextValueIndex2 + 1 : 0;liveData2[nextValueIndex2] = nextValue;vline2.IsVisible = true;vline2.X = nextValueIndex2;}void UpdateData3(double dto){// "scroll" the whole chart to the left// Array.Copy(liveData, 1, liveData, 0, liveData.Length - 1);// place the newest data point at the enddouble nextValue = dto;nextValueIndex3 = (nextValueIndex3 < liveData3.Length - 1) ? nextValueIndex3 + 1 : 0;liveData3[nextValueIndex3] = nextValue;vline3.IsVisible = true;vline3.X = nextValueIndex3;}void Render(object sender, EventArgs e){AvaPlot1.Refresh();AvaPlot2.Refresh();AvaPlot3.Refresh();}private void InitializeComponent(){AvaloniaXamlLoader.Load(this);}protected override void OnClosing(CancelEventArgs e){this.Hide();base.OnClosing(e);}}

UpdateData方法就是用来更新心电图表的方法, 根据消息队列数据去更新是视图中的ScottPlot 图表

相关文章:

avalonia、WPF使用ScottPlot动态显示ECG心电图

文章目录 avalonia、WPF使用ScottPlot动态显示ECG心电图实现效果&#xff0c;动态效果懒得录视频了安装代码部分UpdateData方法就是用来更新心电图表的方法&#xff0c; 根据消息队列数据去更新是视图中的ScottPlot 图表 avalonia、WPF使用ScottPlot动态显示ECG心电图 avalonia…...

国内数学公式识别软件对比

1. 超级公式 官网 https://www.ocrmath.com/ 目前超级公式最好用 2. 极度公式 官网 https://jidugs.wrste.com/ 季度公式也还可以&#xff0c;之前提了一些改进用户建议&#xff0c;很久都不改&#xff0c;遂改用超级公式 3. SimpleTex 官网 https://simpletex.cn/ 最近才…...

SCOPE_IDENTITY什么意思

在关系型数据库中&#xff0c;SCOPE_IDENTITY()是一个用于获取最近插入的行的自增标识列值的函数。当向数据库表中插入一行数据时&#xff0c;如果表中的某列被配置为自增标识列&#xff08;通常是主键列&#xff09;&#xff0c;数据库会自动为每个插入的行分配一个唯一的值&a…...

构建现代应用:Java中的热门架构概览

文章目录 1. 三层架构2. Spring框架3. 微服务架构4. Java EE&#xff08;Enterprise Edition&#xff09;5. 响应式架构6. 大数据架构7. 领域驱动设计&#xff08;Domain-Driven Design&#xff0c;DDD&#xff09;8. 安卓开发架构结论 &#x1f389;欢迎来到Java学习路线专栏~…...

Axure RP软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Axure RP是一款专业的原型设计工具&#xff0c;它能够帮助用户创建高保真度的交互式原型。 Axure RP具有以下特点&#xff1a; 强大的交互设计功能&#xff1a;Axure RP提供了丰富的交互设计工具&#xff0c;用户可以通过拖拽和…...

关于微信小程序的生命周期

关于微信小程序的生命周期 onLaunch 官网App.vue/App.uvue | uni-app官网 问题描述&#xff1a;我现在有个小程序 取名为a 有个用户b 从来没有打开过小程序 那么他第一次打开小程序的时候会触发onLaunch 然后用户b退出了小程序 那么用户 b重新打开小程序的时候会触发 onL…...

【数据结构】带头双向循环链表及其实现

目录 1.带头双向循环链表 2.带头双向循环链表实现 2.1初始化 2.2销毁 2.3头插 2.4链表打印 2.5头删数据 2.6尾插数据 2.7尾删数据 2.8链表判空 2.9查找一个数据 2.10在pos位置前插入数据 2.11删除pos位置 2.12求链表的长度 2.顺序表和链表的比较 1.带头双向循环…...

问道管理:日换手率达20是好是坏?

关于股票商场的出资者而言&#xff0c;日换手率是一个非常重要的目标。日换手率是指股票当日买卖量与该股总股本之比。假如一只股票的日换手率过高&#xff0c;那么就意味着该股票的流动性较强&#xff0c;而假如日换手率过低&#xff0c;那么就意味着该股票的流动性较弱。 那…...

勃艮第葡萄酒是如何分级的?

勃艮第葡萄酒来自一个同名的地区:勃艮第&#xff0c;它位于法国中东部&#xff0c;在西部的卢瓦尔河和东部的索恩河之间。该地区最大的城市是欧塞尔、第戎、马孔和内韦尔。由于地处国家中心&#xff0c;勃艮第属于大陆性气候&#xff0c;夏季炎热&#xff0c;冬季寒冷。这种气候…...

使用awvs进行web安全扫描

1、安装 docker pull secfa/docker-awvs docker run -it -d -name awvs -p 13443:3443 --cap-add LINUX_IMMUTABLE secfa/docker-awvs2、账号密码 # https://ip:13443/ # 用户名:adminadmin.com # 密码:Admin1233、使用 ps:需要征得甲方的同意...

抖音小程序开发教学系列(1)- 抖音小程序简介

章节一&#xff1a;抖音小程序简介 1.1 抖音小程序的背景和概述 抖音小程序的发展背景和市场趋势&#xff1a; 抖音作为一款热门的短视频社交平台&#xff0c;用户群体庞大&#xff0c;社交共享的特性也为小程序的发展提供了广阔的空间。抖音小程序作为抖音在社交和用户粘性…...

【4.Vue兄弟组件之间传值-Bus总线】

1.概述 通过创建一个新的vm对象,专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果 也就是:各个组件内部要传输的数据或者要执行的命令信息,靠bus来通信。 2. 代码实现 2.1 全局引入 全局引入的话,就直接在main.js里面引入即可: // 创建 bus总线 V…...

element中Notification组件(this.$notify)自定义样式

1、自定义样式效果 2、vue代码 this.notifications this.$notify({title: ,dangerouslyUseHTMLString: true,duration: obj.remindMethod3 ? 0:4500,customClass: notify-warning,offset: 50,showClose: false,message: this.$createElement("div",null,[this.$…...

Manjaro安装使用

Manjaro安装使用 1.先更改镜像源&#xff1a;sudo pacman-mirrors -c China -g 2.安装第三方软件管理工具 &#xff1a;sudo pacman -Sy yay 导入GPG Key sudo pacman -Syy && sudo pacman -S archlinuxcn-keyring安装输入法 sudo pacman -S fcitx-im (#默认全部安装…...

【iOS】折叠cell

文章目录 前言一、实现效果二、折叠cell的实现原理三、实现折叠cell的高度变化四、实现选中点击的单元格总结 前言 在暑假的3GShare中用到了折叠cell控件&#xff0c;特此总结博客记录 一、实现效果 二、折叠cell的实现原理 首先我们需要知道ScrollView的是TableView的父类&a…...

无涯教程-Android - DatePicker函数

Android Date Picker允许您在自定义用户界面中选择由日,月和年组成的日期。为此功能,android提供了DatePicker和DatePickerDialog组件。 在本教程中,我们将通过DatePickerDialog演示日期选择器的用法, DatePickerDialog是一个包含DatePicker的简单对话框。 为了显示DatePicker…...

经纬恒润荣获吉利汽车“最佳价值贡献”奖

8月18日&#xff0c;以“全面向新 共创共赢”为主题&#xff0c;吉利汽车在宁波成功举行2023年电子电器核心供应商恳谈会。经纬恒润凭借在项目合作上持续创新、高效协同等优异表现&#xff0c;获得“最佳价值贡献”奖项。 作为国产汽车代表性品牌之一&#xff0c;吉利汽车积极推…...

【多线程】lock与synchronized的区别

相同点&#xff1a; 1、他们都是Java中用于解决线程安全的工具&#xff0c;两者的性能相差不大 不同点&#xff1a; 1、在实现上synchronized引入了偏向锁、轻量级锁、重量级锁、锁升级来优化加锁的性能&#xff0c;而lock则使用自旋锁来实现性能的优化 2、synchronized是J…...

什么是RTC

参考&#xff1a; https://zhuanlan.zhihu.com/p/377100294 RTC&#xff08;Real time communication&#xff09;实时通信&#xff0c;是实时音视频的一个简称&#xff0c;我们常说的RTC技术一般指的是WebRTC技术&#xff0c;已经被 W3C 和 IETF 发布为正式标准。由于几乎所…...

BW 源/目标模型主键不一样,增量的作用

最近项目上&#xff0c;做了一个复杂的需求逻辑&#xff0c;源模型到目标模型&#xff0c;主键完全发生了变化。用转换的传统功能&#xff0c;我担心处理起来不方便就使用了专家历程&#xff08;这个说明在之前有说过&#xff09;。 项目上线后&#xff0c;发生很多异常事件。但…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...