简介
随着大数据的蓬勃发展,各行业对数据价值的重视程度增加。大屏可视化也已经在各个企业中应用。本节介绍如何从 0 到 1 实现一个简单大屏项目。
搭建项目
- 快速搭建项目,使用脚手架
create-react-app
创建。 - 搭建项目,详细流程 基础-搭建react项目教程。
npx create-react-app 项目名
- 进入项目根目录,添加可视化工具。
- DataV,提供了很多边框和一些大屏需要的组件。
npm i @jiaminghi/data-view-react
- echarts,图表绘制工具,你能想到的它基本都有。
npm i echarts
- 一个简单的项目就搭建完成了。这个示例项目中我把多余的文件都删除了。
大屏适配
- 大屏项目需要在不同分辨率下进行展示,所以在开发前就需要确认选用什么方式进行适配。
- 这里主要介绍
3、4
两种方式,常用方式:
px
转vh\vw
或%
比。
- 根据设计图的
px
尺寸,把宽高分层100份。在开发时,所有的长度单位都按这份比例来编写。
- 媒体查询
@media
。
- 根据设计图,在不同分辨率下写出对应的样式。需要写大量的样式,定制化要求不多就不要考虑。
@media only screen and (max-width: 1000px) {
.div-class { width: 720px; }
}
@media only screen and (max-width: 1920px) {
.div-class { width: 1200px; }
}
px
转rem
。
CSS
中规定1rem
的大小就是根元素<html>
的font-size
的值。- 当使用了其他组件,其内部设置的都是
px
。需要在添加一个根据font-size
的值计算当前比例下设置的长度转换为对应的px
值。 - 监听
onresize
方法,实时计算当前分辨率下font-size
的值。开发时全程使用rem
布局。
// 计算 fontSize
function setFontSize() {
let designWidth = 1920
let designHeight = 1080
var fontSize =
document.documentElement.clientWidth / document.documentElement.clientHeight
< designWidth / designHeight
? (document.documentElement.clientWidth / designWidth) * 100
: (document.documentElement.clientHeight / designHeight) * 100
document.querySelector('html').style.fontSize = fontSize + 'px'
}
// 防抖 在一定时间内 只执行最后一次
const debounce = (fn, delay) => {
let timer
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn()
}, delay)
}
}
.App {
height: 100vh;
width: 100vw;
font-size: 16px;
}
.box-x {
width: 4rem;
height: 2rem;
}
- 使用。
useEffect(() => {
setFontSize()
const cancalDebounce = debounce(setFontSize, 100)
// 监听
window.addEventListener('resize', cancalDebounce)
return () => {
// 移除
window.removeEventListener('resize', cancalDebounce)
}
}, [])
transform
属性的scale
方法。
- 计算缩放比,对整个元素进行缩放。
// 缩放比
function scale() {
let designWidth = 1920
let designHeight = 1080
let scale =
document.documentElement.clientWidth / document.documentElement.clientHeight
< designWidth / designHeight
? document.documentElement.clientWidth / designWidth
: document.documentElement.clientHeight / designHeight
return scale
}
.App {
width: 1920px;
height: 1080px;
transform-origin: 0 0;
position: absolute;
left: 50%;
top: 50%;
}
.box-x {
width: 400px;
height: 200px;
}
- 使用
const [state, setState] = useState({ scale: 1 })
useEffect(() => {
setState({
scale: scale()
})
window.onresize = function () {
setState({
scale: scale()
})
}
return () => {
// 清除
window.onresize = null
}
}, [])
<div
className="App"
style={{
transform: `scale(${state.scale}) translate(-50%,-50%)`
}}
>...</div>
小结
适配方案除了本节介绍的还有有很多。目前没有完美的方案,或多或少都有一点问题。比如等比缩放,当比例不对时会出现留白。百分比计算,当比例不对时会出现拉伸。开发中都是根据客户需求进行一步步优化,以求达到完美。
布局
- 在拿到设计图后,通过设计图的布局来对页面进行层级划分,一般情况都是两层,背景层、图表层。当需要使用地图时,背景层就变成地图层。
- 在开发时,每个图表都应该是一个单独的组件。这样能减少代码的耦合和多人开发时的冲突。
- 这里使用的是第4种适配方案,因为没有设计图就随意开发了。
- 使用等比缩放方案,所有布局按设计稿开发就行。
- 需要注意
CSS
命名需要一定规则,防止不同组件中的样式冲突。
// App.js
import { useState, useEffect } from 'react'
import { scale } from './util'
import { Box1, Box2, Box3, Box4, Box5, Head } from './content'
import './App.css'
function App() {
const [state, setState] = useState({ scale: 1 })
useEffect(() => {
setState({
scale: scale()
})
window.onresize = function () {
setState({
scale: scale()
})
}
return () => {
// 清除
window.onresize = null
}
}, [])
return (
<div
className="App"
style={{
transform: `scale(${state.scale}) translate(-50%,-50%)`
}}
>
<Head></Head>
<Box1 />
<Box2 />
<Box3 />
<Box4 />
<Box5 />
</div>
)
}
export default App
- 代码比较多,这里就展示下目录。
- 图表层的内容,都是存放在
content
目录下的。
绘制图表
- 可视化开发工具很多,选择适合自己项目的就行了。
- 本节选用的是
echarts
图表库,先简单的介绍一下它。
使用echarts
- echarts 官网
- 可随意切换
Canvas、SVG
两种渲染方式。 - 企业中常用的图表都支持。
- 是高级图表库,通过配置信息绘制图表。
- 能配合百度地图进行可视化开发。
// content/Box1/Box.jsx
import { useEffect } from 'react'
import { BorderBox1 } from '@jiaminghi/data-view-react'
import * as echarts from 'echarts'
import './box.css'
function Box() {
useEffect(() => {
const chartDom = document.getElementById('box1-main')
const myChart = echarts.init(chartDom)
const option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center',
textStyle: {
color: '#fff'
}
},
series: [
{
name: '职位',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center',
textStyle: {
color: '#fff'
}
},
emphasis: {
label: {
show: true,
fontSize: '40',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{ value: 1048, name: '后端' },
{ value: 735, name: '前端' },
{ value: 580, name: 'IOS' },
{ value: 484, name: '安卓' },
{ value: 300, name: '大数据' }
]
}
]
}
option && myChart.setOption(option)
}, [])
return (
<div className="box-1">
<BorderBox1>
<div id="box1-main" style={{ width: '590px', height: '500px' }}></div>
</BorderBox1>
</div>
)
}
export default Box
echarts
的使用就这么简单,配置好option
属性就会自动绘制图表。- 想深入了解的多去看看示例,echarts 示例。
- 在每一个组件中完善图表,一个简单的大屏可视化项目就完成了。
总结
大屏可视化项目最重要的是尺寸适配,后续出问题多的都是适配没做好。当然做的时候也需要细心,关注设计搞的颜色、尺寸、图表样式等。一些小的差异在放大后也会影响美观。
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。