本项目是学习前端可视化的练习项目,仿制开源项目制作。使用到的技术栈:React、ReactRouter、Echarts。
先放一个预览地址:点击查看效果
gif预览:
使用 rem
适配屏幕
rem
是一个相对长度单位,意为 root em
,是相对于根元素(通常是<html>
元素)的字体大小来计算的。
算法
Wp为页面有效宽度,Hp为页面有效高度。
页面左右居中,上下居中。
若页面宽/高
>16/9
,就左右留白。若页面宽/高
<16/9
,就上下留白。
使用rem
#设置rem
在head
里设置
获取设备宽高,并得到页面宽高
const clientWidth = document.documentElement.clientWidth // 得到设备宽度
const clientHeight = document.documentElement.clientHeight // 得到设备高度
const pageWidth = clientWidth / clientHeight > 16 / 9 ? clientHeight * (16 / 9) : clientWidth; // 定义页面宽度
const pageHeight = pageWidth / (16 / 9) // 定义页面高度
在这里设置 1rem(html
font-size
) = pageWidth/100 px
const string = `<style>html{font-size: ${pageWidth/100}px}</style>`
document.write(string)
#用rem表达页面宽
假设某div
在设计稿中长100px,设计稿整体宽度2420px。那么该div
在页面中长为100 / 2420 * 100rem
。
#px()
函数
按照上方公式,新建一个px.ts
文件,声明全局函数px()
并导出,就可以愉快的使用px(设计稿像素)
了
export const px = (n) => n / 2420 * (window as any).pageWidth;
页面布局
页面布局使用的是Grid
布局,因为Grid布局很方便,跟“切块”的项目适配。
直接上代码
// tsx
<div className="home">
<main>
<section className="section1">
<Chart1/>
<Chart2/>
<Chart3/>
</section>
<section className="section2">
<Chart4/>
<Chart5/>
<Chart6/>
</section>
<section className="section3">
<Chart7/>
<Chart8/>
<Chart9/>
</section>
</main>
</div>
// scss
.home {
flex: 1;
display: flex;
flex-direction: column;
> main {
width: px(2420);
margin: 0 auto;
padding: px(74) px(70) px(70) px(70);
flex: 1;
display: grid;
grid-template:
"box1 box2 box3" 1219fr / 557fr 1133fr 557fr;
grid-column-gap: px(19);
grid-row-gap: px(19);
> section {
text-align: center
}
> .section1 {
grid-area: box1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
> .section2 {
grid-area: box2;
display: flex;
flex-direction: column;
justify-content: space-between;
}
> .section3 {
grid-area: box3;
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
}
echarts
使用echarts图表库,主要参考了官方配置手册和术语速查手册
chart1源码,以chart1模组为例,主要用到了useEffect
。
热点地图
官方给出的示例采用百度地图,但考虑到整体效果,我从网上找了一个去除南海的中国地图,当然需要标注地图仅显示中国部分区域。
参考官方文档geo,在geo
中将注册的json地图'CN'
设为map
。
在serues
中设置coordinateSystem: 'geo'
,即可使用。
实时更新数据
实现更新数据也很简单,重新设置echarts的options即可。
还是以chart1为例,放一下改写代码的过程。
// 改写前
export const Chart1 = () => {
const divRef = useRef(null);
useEffect(() => {
var myChart = echarts.init(divRef.current);
myChart.setOption({
...
...
})
},[])
return(
... // 写js
)
}
// 改写后
export const Chart1 = () => {
const divRef = useRef(null);
const myChart = useRef(null);
const data = [
{value: 15, name: '华东'},
{value: 14, name: '华南'},
{value: 13, name: '华北'},
{value: 12, name: '西南'},
{value: 11, name: '西北'},
{value: 10, name: '东北'},
]
useEffect(() => {
setInterval(() => {
const newData = [
{value: 2 + Math.round(Math.random() * 15), name: '华东'},
{value: 2 + Math.round(Math.random() * 15), name: '华南'},
{value: 2 + Math.round(Math.random() * 15), name: '华北'},
{value: 2 + Math.round(Math.random() * 15), name: '西南'},
{value: 2 + Math.round(Math.random() * 15), name: '西北'},
{value: 2 + Math.round(Math.random() * 15), name: '东北'},
];
x(newData)
},1000)
},[])
const x = (data) => {
myChart.current.setOption(({
...
...
}))
}
useEffect(() => {
myChart.current = echarts.init(divRef.current);
x(data)
}, []);
return(
... // 写js
)
}