前言
作为一个今年刚毕业的弟弟来说,刚接到这个需求真是又兴奋,又紧张。
兴奋的是可视化是我觉得非常炫酷的一个功能,做好的一定会很有成就感;
紧张的是组内只有我一个前端,而且还是一个刚毕业的弟中弟;
不管了,冲就完事了!萨斯给!
可视化技术栈:react,echarts,react-for-echarts,sass
布局(这里采用的是我在实际项目中的配置)
- 设置项目的最小宽度 min-width,确保项目不会过于小导致布局混乱
- 横向自适应宽度:采用ant-design的栅栏布局
- 纵向自适应高度,我一开始采用的是rem的适应方案,可是发现有如下问题
-
rem方案使用的是这篇文章的方案,大家可以看看工程运用那里,我关于rem的计算方案并不是采用的该文章的方法,如果你使用的是vscode,那有款cssrem的插件很适合你
-
会修改根元素的font-size,容易导致项目的其他页面字体大小有问题(可通过修改document.body.fontSize来解决)
-
如果放在大屏上,比如分辨率为1920*1080以上,屏幕下方会留白(对rem方案的不熟练)
-
于是,我采用的是vh的方案,查看caniuse,发现兼容性还不错
可视化组件的背景图片
svg作为背景图片带来的坑:
一开始ued给我的切的svg,也没做过可视化,不太懂,也是欣然接受并使用的svg作为背景图片,可是发现调整屏幕的分辨率,组件自适应了,但是背景图却有问题,高度和宽度一致是按照一定比例来缩放的。后来发现原来这是svg的特性,怪不得很适合用来做icon。
于是我使用了svg-to-png,采用png来设置背景图片,并通过调整css来实现背景图片覆盖整个组件。
@mixin background($urlImg) {
background-image: url($urlImg);
background-size: 100% 100%;
background-repeat: no-repeat;
}
世界地图并实现地图下钻
- 首先得把世界地图和各个国家的地图找到,这是一个很庞大的工作。而且以前的地图和现在的地图并非一致,请合理使用(毕竟地球的板块是在不断的运动中的)。
-
中国->国、省、市地图Json(由于有datav官方维护,地图数据新)
-
中国->省、市、区/县地图Json(地图数据新)
-
世界->各个国家的地图Json(包括世界地图)(地图数据旧)
-
世界->各个国家的地图Json(不包括世界地图)(地图数据较新)
-
全世界地图数据集(只更新到了2015年的数据)
-
当你找到json的地图,放上来看看是否一致(权威地图,地图数据新)
-
如果不懂geoJson规范,可看GeoJSON格式规范说明
-
找到了地图json,下钻实现
// 获取地图json注册地图 // map为json所对应的名称(比如:世界地图为world,中国地图为China) registerMap = async map => { // 由于json是存在静态资源中的 const path_env = process.env.NODE_ENV === 'development' ?
/public/json/${map}.json:/assets/public/json/${map}.jsonawait axios(path_env) .then(res => { echarts.registerMap('world', res.data) }) .finally(() => { // 使用的是echarts-for-react,this.echartsReact获取到的是该图表实例 this.echartsReact.dispatchAction({ type: 'restore' }) }) }
词云
我采用的库是TagCloud,同事推荐的一个小巧,可定制的库,挺好用的。
自定义一个时钟
- 使用一个组件来显示时钟,保证时钟的渲染在该组件内进行,不影响其他组件
- 字体样式采用免费可商用的「优设标题黑」
import React, { PureComponent } from 'react'
import dayjs from 'dayjs'
export default class DataVisual extends PureComponent {
state = {
time: dayjs().format('YYYY.MM.DD HH:mm:ss')
}
timer = null
componentDidMount() {
this.timer = setInterval(() => {
this.setState({
time: dayjs().format('YYYY.MM.DD HH:mm:ss')
})
})
}
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return <div style={{ display: 'inline-block' }}>{this.state.time}</div>
}
}
使用@font-face
@font-face {
font-family: electronicNumber;
src: url('./font/DS-DIGI-1.ttf'), url('./font//DS-DIGIB-2.ttf'), url('./font//DS-DIGII-3.ttf'), url('./font/DS-DIGIT-4.ttf');
}
.myFontFace {
font-family: electronicNumber;
}
使用@media
@mixin screenMedia($fontSize) {
// 如果小于1440px,则font-size生效
// 同理min-width:1440px,如果大于1440px,则font-size生效
@media screen and (max-width: 1440px) {
font-size: $fontSize
}
}
.mymMedia{
@include screenMedia(20px);
}
文章针对前端可视化的大屏展示,根据需求来完善文章,欢迎各位大佬评论哦。
如果有需要修改文章的内容,我会改进。
附上一张性能图片,小弟还没做过这方面的优化,性能还是有很多需要优化的地方。