React18使用Echarts和MUI實現一個交互性的溫度計
前言
在本文中,我們將結合使用React 18、Echarts和MUI(Material-UI)庫,展示如何實現一個交互性的溫度計。我們將使用Echarts繪制溫度計的外觀,并使用MUI創(chuàng)建一個漂亮的用戶界面。
本文將詳細介紹實現溫度計所需的關鍵代碼以及其他必要的步驟,本文會盡可能的提供詳細的注釋。
完成后的樣式

關鍵代碼
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 = [];
// 創(chuàng)建刻度數據
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); // 定義最大溫度的狀態(tài)值,默認為80
const [minTemperature, seMinTemperature] = React.useState<number>(-20); // 定義最小溫度的狀態(tài)值,默認為-20
return (
<Box
ref={parentRef}
sx={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
color: '#fff'
}}
>
{isMinHieght ?
<Box
sx={{
display: 'flex',
flexDirection: 'column',
textAlign: 'left'
}}
>
<Box
sx={{
display: 'flex',
alignItems: 'center',
mb: 2
}}
>
<Box
sx={{
borderLeft: '10px solid transparent',
borderRight: '10px solid transparent',
borderBottom: '20px solid #FF4D4F',
width: 0,
height: 0,
display: 'inline-block'
}}
></Box>
<span
style={{
paddingLeft: '4px'
}}
>
最高溫度
{parseFloat(String(maxTemperature)).toFixed(1)}℃
</span>
</Box>
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}
>
<Box
sx={{
borderLeft: '10px solid transparent',
borderRight: '10px solid transparent',
borderTop: '20px solid #5087EC',
width: 0,
height: 0,
display: 'inline-block'
}}
></Box>
<span
style={{
paddingLeft: '4px'
}}
>
最低溫度
{parseFloat(String(minTemperature)).toFixed(1)}℃
</span>
</Box>
</Box> :
<Box
sx={{
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)'
}}
>
<Box
sx={{
position: 'absolute',
top: '-25px',
right: '-30px',
display: 'flex',
alignItems: 'center',
fontSize: '12px'
}}
>
<Box
sx={{
marginRight: '10px',
display: 'flex',
alignItems: 'center'
}}
>
<Box
sx={{
borderLeft: '8px solid transparent',
borderRight: '8px solid transparent',
borderBottom: '14px solid #FF4D4F',
width: 0,
height: 0,
display: 'inline-block'
}}
></Box>
<span
style={{
paddingLeft: '4px'
}}
>
最高
</span>
</Box>
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}
>
<Box
sx={{
borderLeft: '8px solid transparent',
borderRight: '8px solid transparent',
borderTop: '14px solid #5087EC',
width: 0,
height: 0,
display: 'inline-block'
}}
></Box>
<span
style={{
paddingLeft: '4px'
}}
>
最小
</span>
</Box>
</Box>
<Box
sx={{
position: 'absolute',
left: '50%',
top: '10px'
}}
>
{/* <span>℃</span> */}
</Box>
<Box
sx={{
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'
}}
>
<hr
style={{
position: 'relative',
margin: 0,
color: '#FF4D4F',
border: 'none',
borderTop: '1px solid #FF4D4F'
}}
/>
<Box
sx={{
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>
<Box
sx={{
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'
}}
>
<hr
style={{
position: 'relative',
margin: 0,
border: 'none',
borderTop: '1px solid #5087EC'
}}
/>
<Box
sx={{
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庫展示了如何實現一個交互性的溫度計。我們通過創(chuàng)建一個溫度計組件,并使用Echarts庫繪制溫度計的外觀。使用MUI庫,我們創(chuàng)建了一個漂亮的用戶界面來容納溫度計。如果不使用MUI,只需要把MUI相關標簽改成HTML標簽即可。
到此這篇關于React18使用Echarts和MUI實現一個交互性的溫度計的文章就介紹到這了,更多相關React Echarts實現溫度計內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
React?錯誤邊界Error?Boundary使用示例解析
這篇文章主要為大家介紹了React?錯誤邊界Error?Boundary使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09

