社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
近来在学习react,过年武汉肺炎导致哪儿也不能去,闲来无事,于是结合武汉肺炎这一热点,使用react的umi框架写了个实时展示肺炎数据的项目
本项目使用腾讯的数据,使用bizcharts实现数据的地图样式可视化,表格可以展示不同城市的情况
本来还以为要通过写爬虫获取数据写入数据库编写api,通过访问api获取数据,但是分析完腾讯的实时数据后发现,可以直接使用腾讯的api。
百度收搜实时信息:
通过分析网站后发现可以通过https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=&_=时间戳
的url获取实时数据
为json数据,数据有如下几个部分:
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目录为各个页面展示以及功能组件
开放对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': '' },
},
},
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
}
})
}
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
}
}
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}
}
}
}
interval
实现定时刷新数据,这里设置60sthis.props.dispatch({type:"wuhan/getWuhanInfo"})
访问models
中的wuhan
的getWuhanInfo
函数@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>
)
}
}
使用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)
}, [])
使用了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
}
antd
的Radio
组件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
更改store
中mapType
的内容,进而更改展示数据
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];
}
});
});
antd
的Table
组件pagination={{hideOnSinglePage:true, pageSize:50}}
设置页码columns
中的className
设置表格中内容的style
4. 表格支持树形数据的展示,当数据中有 children
字段时会自动展示为树形表格,如果不需要或配置为其他字段可以用 childrenColumnName
进行配置。
项目还未写完,有些功能展示还没写,如切换累计数据还是今天新增、外国数据展示、时间序列数据展示等,详细代码就不公开了,之后可能会写教程,随缘。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!