React based large screen monitoring
Technology stack
- React
- ReactRouter
- Echarts
Project introduction
- This project was written to familiarize yourself with front-end visualization while learning about Echarts
- The page layout combines Flex with Grid
- Use REM to match different screen sizes
- Statistics, ring charts, bar charts, maps, etc. in the project come from Echarts, which can update data in real time
- The data in this project is not real data, but written for presentation
- I found dataV after writing the project. It seems to be directly used for visual update. I will try to use it next time
preview
- Preview the address
- Making the address
Screen adaptation
Screen adaptation
- The design is 16:9, and the ideal large screen is 16:9
- If the screen is wide, sway the play
- If the screen is very high, play it up and down
- The formula
- Wp is the page effective width, Hp is the page effective height
- Page left and right center, center, around the white can be
- The first case: the device is very wide, so the page height is the height of the screen, and the page width is calculated proportionally
- The second case: the equipment is very high, on the play. The width of the page is the width of the screen, and the page height is calculated by 16:9
- Then set 1rem = Wp / 100 with JS in head.
- You can also set
- Header: fixed width
Header: {width: px(2420); margin: 0 auto; }Copy the code
- The width of main is about the width of the play
main {
width: px(2420);
margin: 0 auto;
}
Copy the code
Rem calculation formula
1. Rem formula
- The size of a div on the page/the width of the page = the size of a div on the page/the width of the page
- 1rem = Wp / 100 launch: page width = 100*rem
- In combination with the above two points, it can be concluded that: div size on the page = (div size in the design/width of the design) * 100 * REM
- Suppose a div is 100px long and 1920px wide in your design,
- The div is then 100/1920 X 100rem in length on the page
- Finally, we can write a px() function to calculate rem for 100px
Rem is actually the font size in HTML
- Review the rem
< script > const clientWidth = document. DocumentElement. ClientWidth/width/device const clientHeight = Document. The documentElement. ClientHeight window. / / equipment highly pageWidth = clientWidth/clientHeight > 16/9? clientHeight * (16 / 9) : clientWidth; // pageWidth const pageHeight = pageWidth/(16/9) // pageHeight const string = '<style> HTML {font-size:${pageWidth/100}px // 1rem </script> </head> <body> <div id="root"></div> <script> // root.style.width = pageWidth +'px' root.style.height= pageHeight+ 'px' root.style.marginTop = (clientHeight - Margin-top </script> <script type="module" SRC ="/ SRC /main.tsx"></script> </body>Copy the code
Code: Show a div
- Not PX, rem
- How do I convert PX to REM?
- Div size on the page = (div size in the design/width of the design) * 100 * rem
- In the SCSS file
@function px($n){
@return $n/2420*100rem
}
Copy the code
- use
height: px(40);
Copy the code
Flex and Grid layouts
- To fill the page with main
- Level: root> App> Home > Header + main
- The Flex layout is set up for each layer
flex:1; Display: flex; // Use flex layout flex-direction:column; // The arrangementCopy the code
- Home includes header and main
- html
<div className="home">
<header style={{backgroundImage:`url(${headerBg})`}}></header>
<main>
<section className="section1"></section>
<section className="section2"></section>
<section className="section3"></section>
<section className="section4"></section>
<section className="section5"></section>
</main>
</div>
Copy the code
- The CSS uses the grid layout
@import ".. /shared/helper"; .home{ flex:1; display: flex; flex-direction:column; > header{ height:px(99); background-size:cover; } > main { flex: 1; display: grid; grid-template: "box1 box2 box4 box5" 755fr "box3 box3 box4 box5" 363fr / 366fr 361fr 811fr 747fr; > .section1 { grid-area: box1; background: pink; } > .section2 { grid-area: box2; background: lightgray; } > .section3 { grid-area: box3; background: lightblue; } > .section4 { grid-area: box4; background: lightcyan; } > .section5 { grid-area: box5; background: lightyellow; }}}Copy the code
Background and border
- Frame:
- Add ::before to section
- Use box-shadow as a shadow
section{ &::before{ content: ''; position: absolute; left: 0; right: 0; bottom: 0; top: 0; border-radius: 4px; box-shadow: 17px 0 0 -16px #0e325f, -17px 0 0 -16px #0e325f, 0 17px 0 -16px #0e325f, 0 -17px 0 -16px #0e325f, 9px 0 0 -8px #0d4483, -9px 0 0 -8px #0d4483, 0 9px 0 -8px #0d4483, 0 -9px 0 -8px #0d4483,; }}Copy the code
The chart
- Use every
- import * as echarts from “echarts”;
const divRef = useRef(null)
useEffect(()=>{
var myChart = echarts.init(divRef.current);
myChart.setOption(createEchartsOptions({
xAxis: {
options
}));
},[])
return (
<div className="title bordered">
<h2>title</h2>
<div ref={divRef} className="chart"></div>
</div>
)
Copy the code
- Section layout
- Each section may contain more than one chart
- Section1 contains chart1 and chart2
<section className="section1">
<Chart1></Chart1>
<Chart2></Chart2>
</section>
Copy the code
- css
- Flex layout
- Chart1 and chart2 are arranged vertically
- space-between
> .section1 {
grid-area: box1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
Copy the code
- Each chart
- It is divided into title area and chart area
- chart1
- Use flex layout overall
- Title uses the H2 tag
<div className=" traffic statistics bordered"> < H2 >< div ref={divRef} className="chart"></div> </div>Copy the code
- css
. Height :px(315); Display :flex; // flex layout flex-direction:column; align-items:center; H2 {// flex-shrink:0; border:1px solid #0a5299; border-bottom-left-radius:4px; border-bottom-right-radius:4px; font-size:px(22); line-height:px(24); // Row height :px(10) px(28); text-shadow: 0 0 px(3) white; }. Chart {// chart area flex:1; //flex width:100%; // full width}}Copy the code
Optimization of Echarts options
- Using Echart to set options, found many options are repetitive, in line with the idea of encapsulation, eliminate duplication
- Create two files:
- BaseEchartOptions: Some basic echartOptions
- CreateEchartsOptions: Process the basic echartOptions and the options specific to each chart to do a consolidation
- code
- baseEchartOptions
import {px} from "./px";
export const baseEchartOptions ={
title: {show: false},
legend: {show: false},
grid:{
x:px(40),
y:px(40),
x2:px(40),
y2:px(40)
},
textStyle:{
fontSize:px(12),
color:'#79839e'
},
}
Copy the code
- createEchartsOptions
- Options parameters include baseEchartOptions and options specific to each chart
import {baseEchartOptions} from './base-echart-options'; import {px} from './px'; Export const createEchartsOptions = (options) => {const result = {// Destruct options... baseEchartOptions, ... options, }; if (! (options? .xAxis? .axisLabel? .fontSize)) { result.xAxis = result.xAxis || {}; result.xAxis.axisLabel = result.xAxis.axisLabel || {}; result.xAxis.axisLabel.fontSize = px(12); } if (! (options? .yAxis? .axisLabel? .fontSize)) { result.yAxis = result.yAxis || {}; result.yAxis.axisLabel = result.yAxis.axisLabel || {}; result.yAxis.axisLabel.fontSize = px(12); } return result; };Copy the code
- use
- import
import {createEchartsOptions} from ".. /shared/create-echarts-options";Copy the code
- Use: pass in the required options to createEchartsOptions for integration
useEffect(()=>{ var myChart = echarts.init(divRef.current); myChart.setOption(createEchartsOptions({ xAxis: { ... }, yAxis: { ... }, series: [...] })); }, [])Copy the code