react:使用umi+antd实现武汉肺炎数据实时展示 - Go语言中文社区

react:使用umi+antd实现武汉肺炎数据实时展示


近来在学习react,过年武汉肺炎导致哪儿也不能去,闲来无事,于是结合武汉肺炎这一热点,使用react的umi框架写了个实时展示肺炎数据的项目

效果展示

本项目使用腾讯的数据,使用bizcharts实现数据的地图样式可视化,表格可以展示不同城市的情况
在这里插入图片描述

获取数据

本来还以为要通过写爬虫获取数据写入数据库编写api,通过访问api获取数据,但是分析完腾讯的实时数据后发现,可以直接使用腾讯的api。

数据来源

百度收搜实时信息:
在这里插入图片描述
通过分析网站后发现可以通过https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=&_=时间戳的url获取实时数据
在这里插入图片描述

数据解析

为json数据,数据有如下几个部分:

  1. chinaTotal:累计的实时数据
  2. lastUpdateTime:更新时间
  3. areaTree:不同地区的数据
  4. chinaDayList:不同日期的数据

在这里插入图片描述

umi项目

umi是蚂蚁金服的底层前端框架,已直接或间接地服务了 600+ 应用,包括 java、node、H5 无线、离线(Hybrid)应用、纯前端 assets 应用、CMS 应用等。
使用方法详细使用方法移步官网 => 地址

组件引用

  "devDependencies": {
    "umi-plugin-antd-theme": "^1.0.15",
    "umi-plugin-react": "^1.15.2"
  },
  "dependencies": {
    "@ant-design/compatible": "0.0.1-rc.1",
    "@ant-design/pro-table": "^1.0.33",
    "ant-design-pro": "^2.3.2",
    "antd": "^3.26.7",
    "axios": "^0.19.2",
    "bizcharts": "^3.5.6",
    "dva": "^2.4.1",
    "jquery": "^3.4.1",
    "moment": "^2.24.0",
    "react-load-script": "0.0.6",
    "redux": "^4.0.5",
    "umi-request": "^1.2.18"
  }

项目结构

由于本项目还有其他内容,武汉肺炎部分为标红部分,config文件负责路由配置等,layouts目录下的是整体的展示部分,models目录为处理数据的逻辑部分,pages目录为各个页面展示以及功能组件
加粗样式

config设置

开放对antd和dva的使用

  plugins: [
    [
      'umi-plugin-react',
      {
        antd: true,
        dva: true,
      },
    ],
  ],

因为直接使用api的话会出现CORS跨域访问错误,要对api的地址设置代理

  proxy: {
    '/api': {
      target:'https://view.inews.qq.com/',
      changeOrigin: true,
      pathRewrite: { '/api': '' },
    },
  },

数据处理及存储更改

在这里插入图片描述

  1. 通过api获取数据,并提取其中的数据
function getInfo() {
    const timeStamp = new Date().getTime()
    const url = `api/g2/getOnsInfo?name=disease_h5&callback=&_=${timeStamp}`
    console.log("api", url)
    return axios.get(url).then(({data}) => {
        const subData = JSON.parse(data.data)
        return {chinaTotal:subData.chinaTotal,
            lastUpdateTime:subData.lastUpdateTime,
            areaTree:subData.areaTree,
            chinaDayList:subData.chinaDayList
        }
    })
}
  1. 获取国内数据和国外数据,并根据dataType获取累计数据或是当日数据
function transData(subData, dataType){
    let key = 0
    const [china] = subData.filter(e => e.name==="中国")
    const subChina = china.children.map((e)=>{
        const {name, children:child} = e
        const children = child.map(e=>{
            key ++
            const {name} = e
            return {key, name, ...e[dataType]}
        })
        key ++
        return {key, name, ...e[dataType], children}
    })
    const otherCountry = subData.filter(e => e.name!="中国").map(e=>{
        const {name} = e
        return {name, ...e[dataType]}
    })
    return {
        chinaToday:china.today,
        otherCountry:otherCountry,
        subChina:subChina
    }    
}
  1. 通过dva维护页面数据状态
    effects为使用saga的异步函数
export default {
    namespace : 'wuhan', 
    state: {chinaTotal:{},
        lastUpdateTime:null,
        chinaDayList:[],
        chinaToday:{},
        otherCountry:[],
        subChina:[],
        dataType:"total",
        mapType:"confirm",
        },
    effects:{
        *getWuhanInfo(action, {call, put, select}) {
            try{
                const {dataType} = yield select (_=>_.wuhan)
                const {chinaTotal, lastUpdateTime, areaTree, chinaDayList} = yield call(getInfo)
                const {chinaToday, otherCountry, subChina} = yield call(transData, areaTree, dataType)
                yield put({type:"init", payload:{chinaTotal, lastUpdateTime, chinaDayList, chinaToday, otherCountry, subChina}})
            }catch(error){
                console.log(error)
            }
        }
    },
    reducers:{
        init (state, {payload:{chinaTotal, lastUpdateTime, chinaDayList, chinaToday, otherCountry, subChina}}) {
            return { ...state, chinaTotal, lastUpdateTime, chinaDayList, chinaToday, otherCountry, subChina}
        },
        changeMapType(state, {payload}){
            return {...state, mapType:payload}
        }
    }
}

页面展示

  1. 通过interval 实现定时刷新数据,这里设置60s
  2. 通过this.props.dispatch({type:"wuhan/getWuhanInfo"})访问models中的wuhangetWuhanInfo函数
  3. 通过@connect()传递数据
@connect()
export default class index extends Component {

  componentDidMount() {
    this.interval = setInterval(() => this.props.dispatch({type:"wuhan/getWuhanInfo"}), 60000);
  }
  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    this.props.dispatch({type:"wuhan/getWuhanInfo"})
    return (
     <div>
      <Row type="flex" justify="center">
        <TotalData/>>
      </Row>
      <br/>
      <Row type="flex" justify="space-between" style={{padding: '0px 15px'}}>
        <Col span={13}>
          <Choice></Choice>
          <MapChart/>
        </Col>
        <Col span={11}>
          <div style={{backgroundColor:'white'}}>
            <ChinaTable/>
          </div>
        </Col>
      </Row>
    </div>
    )
  }
}

组件

在这里插入图片描述

整体数据展示的TotalData组件

在这里插入图片描述
使用hook进行时间的更新

    const getTime = ()=>{
        const date = new Date();
        const nowTime = date.toLocaleString();
        return nowTime
    }

    const [time, setTime] = useState(getTime())
    useEffect(() => {
        const id = setInterval(() => {
            setTime(getTime())
        }, 1000)
        return () => clearInterval(id)
      }, [])

地图可视化数据的MapChart组件

在这里插入图片描述

使用了bizcharts的地图组件,注意点有要在html中添加js文件的使用
在这里插入图片描述
在设置地图color时,由于湖北省的数据过大,正常设置colormap的话其他省的颜色无法区分,于是设置如下拉开颜色范围:

const colormap = ()=>{
  let arr = new Array('#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000')
  for (let i=0; i<60; i++){
    arr.push('#7f0000')
  }
  return arr
}

数据选择的Choice组件

在这里插入图片描述

  1. 使用antdRadio组件
  2. 通过wuhan/changeMapType的函数更改数据
function Choice({dispatch}) {

    function onChange(e) {
        dispatch({type:"wuhan/changeMapType", payload:e.target.value})
    }

    return (
    <div>
      <Radio.Group onChange={onChange} defaultValue="confirm">
        <Radio.Button value="confirm">累计确诊</Radio.Button>
        <Radio.Button value="suspect">疑似病例</Radio.Button>
        <Radio.Button value="heal">累计治愈</Radio.Button>
        <Radio.Button value="dead">累计死亡</Radio.Button>
      </Radio.Group>
    </div>
    )
}

export default connect()(Choice)

通过Radio更改storemapType的内容,进而更改展示数据

  processGeoData = (geoData, dataValue, mapType) => {
    const { features } = geoData;
    features.forEach((one) => {
      const name = one && one.properties && one.properties.name;
      dataValue.forEach((item) => {
        if (name.includes(item.name)) {
          one.value = item[mapType];
        }
      });
    });

展示数据表格的ChinaTable组件

在这里插入图片描述

  1. 使用antdTable组件
  2. 通过pagination={{hideOnSinglePage:true, pageSize:50}}设置页码
  3. 通过columns中的className设置表格中内容的style

在这里插入图片描述
在这里插入图片描述
4. 表格支持树形数据的展示,当数据中有 children 字段时会自动展示为树形表格,如果不需要或配置为其他字段可以用 childrenColumnName 进行配置。

小结

项目还未写完,有些功能展示还没写,如切换累计数据还是今天新增、外国数据展示、时间序列数据展示等,详细代码就不公开了,之后可能会写教程,随缘

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/tonydz0523/article/details/104125310
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢