使用React 18、Echarts和MUI实现温度计
关键词 React 18 Echarts和MUI
前言
在本文中,我们将结合使用React 18、Echarts和MUI(Material-UI)库,展示如何实现一个交互性的温度计。我们将使用Echarts绘制温度计的外观,并使用MUI创建一个漂亮的用户界面。
本文将详细介绍实现温度计所需的关键代码以及其他必要的步骤,本文会尽可能的提供详细的注释。
完成后的样式

关键代码
import React from 'react';
import * as echarts from 'echarts/core';
import { EChartOption } from '../../EChartOption';
import CommonChart from '../../CommonChart';
import { Box } from '@mui/material';interface TemperatureBarProps {deviceData: any;
}const MAX_TEMPERATURE_SOCPE = 120; //温度上限
const MIN_TEMPERATURE_SOCPE = -40; // 温度下限/*** 温度图表组件*/
const TemperatureChart = () => {// 温度数值let TPvalue = MAX_TEMPERATURE_SOCPE;// 刻度数据let kd = [];// 渐变色配置let Gradient = [];// 创建刻度数据for (let i = 0, len = MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE;i <= len;i += 1) {if (i % 20 === 10) {kd.push('');} else if (i % 40 === 0) {kd.push('-48');} else if (i % 8 === 0) {kd.push('-28');} else {kd.push('');}}// 根据温度数值设置渐变色和文本内容if (TPvalue > 20) {Gradient.push({offset: 0,color: '#93FE94'},{offset: 0.5,color: '#E4D225'},{offset: 1,color: '#E01F28'});} else if (TPvalue > -20) {Gradient.push({offset: 0,color: '#93FE94'},{offset: 1,color: '#E4D225'});} else {Gradient.push({offset: 1,color: '#93FE94'});}// 温度图表配置选项const option = {animation: false, // 禁止动画效果title: {text: ' ℃',top: '5px',left: 'center',textStyle: {color: '#fff',fontStyle: 'normal',fontWeight: 'normal',fontSize: '16px',padding: 5}},grid: {left: '45', // 图表距离容器左边的距离bottom: 20, // 图表距离容器底部的距离top: 30 // 图表距离容器顶部的距离},yAxis: [{show: false, // 不显示y轴data: [], // y轴的数据min: 0, // y轴的最小值max: MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE + 10, // y轴的最大值axisLine: {show: false // 不显示y轴的轴线}},{show: false, // 不显示y轴min: 0, // y轴的最小值max: MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE // y轴的最大值},{type: 'category', // 类型为分类position: 'left', // y轴的位置在左边offset: -80, // y轴与图表的偏移量axisLabel: {fontSize: 10, // y轴标签的字体大小color: 'white' // y轴标签的颜色为白色},axisLine: {show: false // 不显示y轴的轴线},axisTick: {show: false // 不显示y轴的刻度线}}],xAxis: [{show: false, // 不显示x轴min: -50, // x轴的最小值max: 80, // x轴的最大值data: [] // x轴的数据},{show: false, // 不显示x轴min: -48, // x轴的最小值max: 120 // x轴的最大值}],series: [{name: '条', // 数据项名称type: 'bar', // 图表类型为柱状图xAxisIndex: 0, // 与第一个x轴关联data: [MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE + 10], // 柱状图的数据barWidth: 18, // 柱状图的宽度,label: {show: true // 显示标签},itemStyle: {color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{offset: 0.05,color: '#5087EC' // 渐变颜色的起始色},{offset: 0.5,color: '#58DBA4' // 渐变颜色的起始色},{offset: 0.6,color: '#FFF81D' // 渐变颜色的中间色},{offset: 0.8,color: '#FA9917' // 渐变颜色的中间色},{offset: 1,color: '#FF4D4F' // 渐变颜色的结束色}]),borderRadius: [8, 8, 2, 2] // 柱状图的圆角样式},z: 2 // 数据系列层叠的顺序值},{name: '圆', // 数据项名称type: 'scatter', // 图表类型为散点图hoverAnimation: false, // 禁止散点图的Hover动画效果data: [0], // 散点图的数据xAxisIndex: 0, // 与第一个x轴关联symbolSize: 18, // 散点图的符号大小itemStyle: {color: '#5087EC', // 散点图的颜色opacity: 1 // 散点图的透明度},z: 2 // 数据系列层叠的顺序值},{name: '刻度', // 数据项名称type: 'bar', // 图表类型为柱状图yAxisIndex: 0, // 与第一个y轴关联xAxisIndex: 1, // 与第二个x轴关联label: {show: true, // 显示标签position: 'left', // 标签的位置在左边distance: 10, // 标签与柱状图的距离color: 'white', // 标签的颜色为白色fontSize: 14, // 标签的字体大小formatter: function (params) {if (params.dataIndex >MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE) {return '';}if (params.dataIndex % 20 === 0) {return params.dataIndex + MIN_TEMPERATURE_SOCPE;}return '';} // 标签的格式化函数},barGap: '-100%', // 柱状图之间的距离data: kd, // 柱状图的数据barWidth: 0.5, // 柱状图的宽度itemStyle: {color: 'white', // 柱状图的颜色为白色barBorderRadius: 120 // 柱状图的圆角样式},z: 0 // 数据系列层叠的顺序值}]} as EChartOption;// 返回渲染图表的组件return <CommonChart option={option} width="100%" height="100%" />;
};export default function TemperatureBar() {const [maxTemperature, setMaxTemperature] = React.useState<number>(80); // 定义最大温度的状态值,默认为80const [minTemperature, seMinTemperature] = React.useState<number>(-20); // 定义最小温度的状态值,默认为-20return (<Boxref={parentRef}sx={{display: 'flex',height: '100%',alignItems: 'center',justifyContent: 'center',position: 'relative',color: '#fff'}}>{isMinHieght ?<Boxsx={{display: 'flex',flexDirection: 'column',textAlign: 'left'}}><Boxsx={{display: 'flex',alignItems: 'center',mb: 2}}><Boxsx={{borderLeft: '10px solid transparent',borderRight: '10px solid transparent',borderBottom: '20px solid #FF4D4F',width: 0,height: 0,display: 'inline-block'}}></Box><spanstyle={{paddingLeft: '4px'}}>最高温度{parseFloat(String(maxTemperature)).toFixed(1)}℃</span></Box><Boxsx={{display: 'flex',alignItems: 'center'}}><Boxsx={{borderLeft: '10px solid transparent',borderRight: '10px solid transparent',borderTop: '20px solid #5087EC',width: 0,height: 0,display: 'inline-block'}}></Box><spanstyle={{paddingLeft: '4px'}}>最低温度{parseFloat(String(minTemperature)).toFixed(1)}℃</span></Box></Box> :<Boxsx={{width: 'calc(100% - 80px)',maxWidth: '140px',height: '80%',background: '#363636',borderRadius: '8px',position: 'relative',boxShadow: '2px 2px 8px 0px rgba(0, 0, 0, 0.7)'}}><Boxsx={{position: 'absolute',top: '-25px',right: '-30px',display: 'flex',alignItems: 'center',fontSize: '12px'}}><Boxsx={{marginRight: '10px',display: 'flex',alignItems: 'center'}}><Boxsx={{borderLeft: '8px solid transparent',borderRight: '8px solid transparent',borderBottom: '14px solid #FF4D4F',width: 0,height: 0,display: 'inline-block'}}></Box><spanstyle={{paddingLeft: '4px'}}>最高</span></Box><Boxsx={{display: 'flex',alignItems: 'center'}}><Boxsx={{borderLeft: '8px solid transparent',borderRight: '8px solid transparent',borderTop: '14px solid #5087EC',width: 0,height: 0,display: 'inline-block'}}></Box><spanstyle={{paddingLeft: '4px'}}>最小</span></Box></Box><Boxsx={{position: 'absolute',left: '50%',top: '10px'}}>{/* <span>℃</span> */}</Box><Boxsx={{position: 'absolute',width: 'calc(50% + 20px)',margin: 0,left: '50%',top: `calc(30px + ((100% - 50px) * (${MAX_TEMPERATURE_SOCPE} - ${maxTemperature} + 10) / ${MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE + 10}))`,transition: 'top 0.3s ease'}}><hrstyle={{position: 'relative',margin: 0,color: '#FF4D4F',border: 'none',borderTop: '1px solid #FF4D4F' }}/><Boxsx={{position: 'absolute',left: 'calc(100% - 10px)',top: '-26px',borderLeft: '10px solid transparent',borderRight: '10px solid transparent',borderBottom: '16px solid #FF4D4F' width: 0,height: 0,display: 'flex',justifyContent: 'center',paddingBottom: '18px'}}>{parseFloat(String(maxTemperature)).toFixed(1)}</Box></Box><Boxsx={{position: 'absolute',margin: 0,width: 'calc(50% + 20px)',left: '50%',top: `calc(30px + (100% - 50px) * (${MAX_TEMPERATURE_SOCPE} - ${minTemperature} + 10) / ${MAX_TEMPERATURE_SOCPE - MIN_TEMPERATURE_SOCPE + 10})`,transition: 'top 0.3s ease'}}><hrstyle={{position: 'relative',margin: 0,border: 'none',borderTop: '1px solid #5087EC' }}/><Boxsx={{position: 'absolute',left: 'calc(100% - 10px)',top: '-8px',borderLeft: '10px solid transparent',borderRight: '10px solid transparent',borderTop: '16px solid #5087EC'width: 0,height: 0,display: 'flex',justifyContent: 'center',paddingTop: '3px'}}>{parseFloat(String(minTemperature)).toFixed(1)}</Box></Box><TemperatureChart /></Box>}</Box>);
}
后言
在本文中,我们使用React 18、Echarts和MUI库展示了如何实现一个交互性的温度计。我们通过创建一个温度计组件,并使用Echarts库绘制温度计的外观。使用MUI库,我们创建了一个漂亮的用户界面来容纳温度计。如果不使用MUI,只需要把MUI相关标签改成HTML标签即可。
相关文章:
使用React 18、Echarts和MUI实现温度计
关键词 React 18 Echarts和MUI 前言 在本文中,我们将结合使用React 18、Echarts和MUI(Material-UI)库,展示如何实现一个交互性的温度计。我们将使用Echarts绘制温度计的外观,并使用MUI创建一个漂亮的用户界面。 本文…...
使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理
1、通用的业务编码规则的管理功能 在前面随笔我们介绍了一个通用的业务编码规则的管理功能,通过代码生成工具Database2Sharp一步步的生成相关的后端和Winform、WPF的界面,进行了整合,通过利用代码生成工具Database2sharp生成节省了常规功能的…...
Android 13 - Media框架(26)- OMXNodeInstance(三)
上一节我们了解了OMXNodeInstance中的端口定义,这一节我们一起来学习ACodec、OMXNode、OMX 组件使用的 buffer 到底是怎么分配出来的,以及如何关联起来的。(我们只会去了解 graphic buffer的创建、input bytebuffer的创建、secure buffer的创…...
力扣题目学习笔记(OC + Swift)21. 合并两个有序链表
21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 链表解题经典三把斧: 哑巴节点栈快慢指针 此题比较容易想到的解法是迭代法,生成哑巴节点,然后迭代生成后续节点。…...
C# WPF上位机开发(windows pad上的应用)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 大部分同学可能都认为c# wpf只能用在pc端。其实这是一种误解。c# wpf固然暂时只能运行在windows平台上面,但是windows平台不仅仅是电脑…...
Word使用技巧【开题报告】
1、修改目录:选中目录,点击更新域。 2、更改或删除单个页面上的页眉或页脚 3、借助其他软件在Word导入参考文献 利用zetero导入文献:安装zetero 解决参考文献插入问题 在Word中插入文献操作步骤 英文文献出现“等”,如何解决 Zote…...
电子学会C/C++编程等级考试2022年06月(七级)真题解析
C/C++等级考试(1~8级)全部真题・点这里 第1题:有多少种二叉树 输入n(1<n<13),求n个结点的二叉树有多少种形态 时间限制:1000 内存限制:65536输入 整数n输出 答案 样例输入 3样例输出 5 答案: //参考答案 #include<bits/stdc++.h> using namespace std; …...
git中的smart checkout和force checkout
切换分支时出现了这个问题: 这是因为shiyan01分支修改了代码,但是没有commit, 所以在切换到test分支的时候弹出这个窗口 一、smart checkout(智能签出) 会把shiyan01分支的改动内容带到test分支。合并处理后的内容就变成了test分支的内容,而shiyan01分支的改动会被…...
vue3整合Element-Plus,极速上手。
条件分页查询: 需求分析: form表单 Button按钮 Table表格 Pagination分页 页面布局: 搜索表单: 如果表单封装的数据较多,建议绑定到一个对象中。 …...
学习Vue2.x
文章目录 一、使用Vue脚手架1.ref和props属性2.mixin混入3.组件化编码流程4.webStorage5.组件自定义事件6.全局事件总线7.消息订阅与发布 二、使用步骤1.引入库 一、使用Vue脚手架 1.ref和props属性 ref属性: (1)被用来给元素或子组件注册应…...
新手如何快速熟悉代码,写出东西(持续更新)
目录 第一章、最小编程任务的设想1.1)程序员入门会遇到的问题1.2)最小编程任务的设想1.3)编程逻辑1.4)具体需求 第二章、最小编程单元的练习2.1)代码/需求方面2.1.1)初级练习2.1.2)中级练习2.1.…...
11-网络安全框架及模型-软件安全能力成熟度模型(SSCMM)
目录 软件安全能力成熟度模型 1 背景概述 2 主要内容 3 成熟度等级定义 4 关键过程和实践 5 评估方法 6 改进建议 7 持续改进 8 主要价值 9 应用场景 10 优势和局限性 备注 软件安全能力成熟度模型 1 背景概述 SSCMM模型是软件安全能力成熟度模型,它描…...
Linux操作系统基础知识点
Linux是一种计算机操作系统,其内核由林纳斯本纳第克特托瓦兹(Linus Benedict Torvalds)于1991年首次发布。Linux操作系统通常与GNU套件一起使用,因此也被称为GNU/Linux。它是一种类UNIX的操作系统,设计为多用户、多任务…...
python 通过opencv及face_recognition识别人脸
效果: 使用Python的cv2库和face_recognition库来进行人脸检测和比对的 0是代表一样 认为是同一人。 代码: pip install opencv-python pip install face_recognition# 导入cv2库,用于图像处理 import cv2 # 导入face_recognition库&#…...
Android开发中常见的Hook技术有哪些?
Hook技术介绍 Hook技术是一种在软件开发中常见的技术,它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作,或者在特定的事件发生时触发自定义的处理逻辑。 在Android开发中,Hook通常是通…...
【linux c多线程】线程的创建,线程信息的获取,获取线程返回值
线程创建 专栏内容: 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构,以及如何实现多机的数据库节点的多读多写,与传统主备,MPP的区别,技术难点的分析,数据元数据同步,多主节点的情况下对…...
MFC或QT中,自绘控件的目的和实现步骤
MFC自绘控件的步骤 自绘控件的目的是为了能够自定义控件的外观、行为和交互方式,以满足特定的需求,同时增强应用程序的用户体验。 实现步骤如下: 1、创建一个继承自MFC控件基类(如CButton、CStatic等)的自定义控件类…...
ceph集群搭建详细教程(ceph-deploy)
ceph-deploy比较适合生产环境,不是用cephadm搭建。相对麻烦一些,但是并不难,细节把握好就行,只是命令多一些而已。 实验环境 服务器主机public网段IP(对外服务)cluster网段IP(集群通信&#x…...
机器视觉系统选型-避免畸变
在定位及高精度测量的系统中,镜头畸变的影响尤其重要 • 使用远心镜头 • 进行系统标定...
机器学习笔记 - 线性判别分析(LDA)的原理和应用
一、LDA简述 线性判别分析(LDA)是监督机器学习中用于解决多类分类问题的一种方法。LDA通过数据降维来分离具有多个特征的多个类。这项技术在数据科学中很重要,因为它有助于优化机器学习模型。 线性判别分析,也称为正态判别分析 (NDA) 或判别函数分析 (DFA),遵循生成模型框…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
