關鍵詞 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
標簽即可。