大屏可视化项目——李白的流浪地图

7,931 阅读3分钟

本项目是学习前端可视化的练习项目,仿制开源项目制作。使用到的技术栈:React、ReactRouter、Echarts。

先放一个预览地址:点击查看效果

gif预览:

libai.1.1.gif

使用 rem 适配屏幕

rem 是一个相对长度单位,意为 root em,是相对于根元素(通常是<html>元素)的字体大小来计算的。

算法

Wp为页面有效宽度,Hp为页面有效高度。

image.png

页面左右居中,上下居中。

若页面宽/高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表达页面宽

image.png

假设某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',即可使用。

Ecahrts官方示例-全国主要城市空气质量-百度地图

# echarts结合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
  )
  }