前端大屏可视化

技术栈

可视化技术栈:react,echarts,react-for-echarts,sass

开始布局啦!


  1. 设置项目的最小宽度 min-width,确保项目不会过于小导致布局混乱
  2. 横向自适应宽度:采用 ant-design 的栅栏布局
  3. 纵向自适应高度,我一开始采用的是 rem 的适应方案,可是发现有如下问题

    • 会修改根元素的 font-size,容易导致项目的其他页面字体大小有问题(可通过修改 document.body.fontSize 来解决)
    • 如果放在大屏上,比如分辨率为 1920*1080 以上,屏幕下方会留白,这是由于 rem 是按照屏幕的比例来进行展示的
  4. 于是,我采用的是 vh 的方案,查看caniuse,发现兼容性还不错,而且适合在各种比例的屏幕上进行显示

rem 布局方案

rem 可以简单的理解为屏幕宽度的百分比

  1. 引入阿里的 flexible来进行屏幕划分,这里默认是将屏幕宽度划分成十等分,如果设计稿为 1920*1080,则 html 根元素的 font-size 为 1920/10 = 192 px
  2. 配置 vscode 的 cssrem 插件的 Root Font Size = 192(如果想直接写 px,可采用postcss-px2rem)

举个例子:设计稿为 1920*1080,实际投屏尺寸为 5760 * 3240

设计稿:

.dom {
  width: 200px;
}

代码:

.dom {
  width: 1.0416666667rem;
}

实际:

// 根html的font-size: 576
.dom {
  // 1.0416666667 * 576
  width: 600px;
}
  1. 让 Echarts 图表根据屏幕宽度的大小变化而自适应,如果使用的是 react-for-echarts 就不用再添加了
window.addEventListener("resize", () => {
  echartsInstance.resize()
})

可视化组件的背景图片


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;
}

世界地图并实现地图下钻


  1. 首先得把世界地图和各个国家的地图找到,这是一个很庞大的工作。而且以前的地图和现在的地图并非一致,请合理使用(毕竟地球的板块是在不断的运动中的)。

  2. 找到了地图 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}.json`
  await axios(path_env)
    .then(res => {
      echarts.registerMap("world", res.data)
    })
    .finally(() => {
      // 使用的是echarts-for-react,this.echartsReact获取到的是该图表实例
      this.echartsReact.dispatchAction({
        type: "restore",
      })
    })
}

词云

我采用的库是TagCloud,同事推荐的一个小巧,可定制的库,挺好用的。

自定义一个时钟

  1. 使用一个组件来显示时钟,保证时钟的渲染在该组件内进行,不影响其他组件
  2. 字体样式采用免费可商用的「优设标题黑」
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

MDN

@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(设置响应式)

MDN

@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);
}

最后

参考:大屏上的全屏页面的自适应适配方案

文章针对前端可视化的大屏展示,根据需求来完善文章,欢迎各位大佬评论哦。
如果有需要修改文章的内容,我会改进。
附上一张性能图片,没做这方面的优化。
> 使用 chrome performance 查看页面性能
> 著名的 RAIL model

Published under  on .

Last updated on .

pipihua

我是皮皮花,一个前后端通吃的前端攻城狮,如果感觉不错欢迎点击小心心♥(ˆ◡ˆԅ) star on GitHub!