申明:学习自B站up:小满zs(https://space.bilibili.com/99210573),仅记录一下学习笔记
数据地址:实时更新:新冠肺炎疫情最新动态 (qq.com)
在控制台网络中查看Fetch/XHR里的list 即为疫情数据
npm install ts-node -g
npm init -y
npm install @types/node -D //node 申明文件
npm install express -S
npm install @types/express -D //express 申明文件
npm install axios -S
import express,{Express,Router,Request,Response} from 'express'
import axios from 'axios'
const app:Express = express()
// 设置跨域允许
app.use('*',(req,res,next) => {
res.header('Access-Control-Allow-Origin','*')
next();
})
const router:Router = express.Router()
app.use('/api',router)
router.get('/list',async (req:Request, res:Response) => {
const result = await axios.post('https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=localCityNCOVDataList,diseaseh5Shelf')
res.json({
data:result.data
})
})
app.listen(3333,()=>{
console.log('server listening on 3333!')
})
疫情数据接口:http://localhost:3333/api/list(个人的)
npm init vue@latest
npm install
要同时安装less和lessload,其实在vite中只需要安装less即可,另一个可以不用安装,vite官网有说明.sass同理
npm install less
npm install axios
import axios from 'axios'
const server = axios.create({
baseURL: "http://localhost:3333",
})
export const getApiList = () => server.get('/api/list').then(res => res.data)
import { defineStore } from 'pinia'
import {getApiList} from '../server'
export const useStore = defineStore({
id:'counter',
state:()=>({
list:{},
}),
actions:{
async getList(){
const result = await getApiList()
console.log(result)
}
}
})
import {useStore} from "./stores"
const store = useStore();
store.getList()
npm install echarts --save-dev
export const geoCoordMap: Record<string, Array<number>> = {
'台湾': [121, 23],
'黑龙江': [127, 48],
'内蒙古': [110.3467, 41.4899],
"吉林": [125.8154, 44.2584],
'北京': [116.4551, 40.2539],
"辽宁": [123.1238, 42.1216],
"河北": [114.4995, 38.1006],
"天津": [117.4219, 39.4189],
"山西": [112.3352, 37.9413],
"陕西": [109.1162, 34.2004],
"甘肃": [103.5901, 36.3043],
"宁夏": [106.3586, 38.1775],
"青海": [99.4038, 36.8207],
"新疆": [87.9236, 43.5883],
"西藏": [88.388277, 31.56375],
"四川": [103.9526, 30.7617],
"重庆": [108.384366, 30.439702],
"山东": [117.1582, 36.8701],
"河南": [113.4668, 34.6234],
"江苏": [118.8062, 31.9208],
"安徽": [117.29, 32.0581],
"湖北": [114.3896, 30.6628],
"浙江": [119.5313, 29.8773],
"福建": [119.4543, 25.9222],
"江西": [116.0046, 28.6633],
"湖南": [113.0823, 28.2568],
"贵州": [106.6992, 26.7682],
"云南": [102.9199, 25.4663],
"广东": [113.12244, 23.009505],
"广西": [108.479, 23.1152],
"海南": [110.3893, 19.8516],
'上海': [121.4648, 31.2891],
'香港': [114.30, 22.9],
'澳门': [113.5, 22.2]
};
使用vscode插件json2ts,将数据放入index.json后 ctrl + alt + v
,即可根据数据自动生成接口
然后在stroes文件夹里引入,即可解决Typescript报错问题,因为如果定义空对象,会默认下面没有其他属性而报错。
添加childrenList数据,用于存储列表数据
为图表添加监听事件,点击打印相关数据,这里点击将store的childrenLIst进行修改,后续用于列表的数据
chart.on('click',(event:any)=>{
// console.log(city)
console.log(event)
store.childrenList = event.data.source.children
console.log(store.childrenList)
})
html:
<table id="customers">
<tr>
<th>名称th>
<th>治愈th>
<th>确诊th>
<th>本土确诊th>
tr>
<tr v-for="(item,index) in store.childrenList" :key="index">
<td>{{item.name}}td>
<td>{{item.total.confirm}}td>
<td>{{item.today.confirm}}td>
<td>{{item.today.local_confirm_add}}td>
tr>
table>
css:
#customers {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 100%;
}
#customers td, #customers th {
border: 1px solid #ddd;
padding: 8px;
}
#customers tr:nth-child(even){background-color: #f2f2f2;}
#customers tr:hover {background-color: #ddd;}
#customers tr {background-color: #ddd;text-align: center}
#customers th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #4CAF50;
// color: rgb(255, 255, 255);
}
安装animate.css: npm install animate.css -S
引入:import 'animate.css'
设置群体动画一定要设置key,且唯一,因为index重复后,有的动画不会展示,因此使用uuid解决唯一值
assets文件夹新建getUUID.ts:
export function getUuid () {
if (typeof crypto === 'object') {
if (typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
const callback = (c) => {
const num = Number(c);
return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(16);
};
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, callback);
}
}
let timestamp = new Date().getTime();
let perforNow = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0;
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
let random = Math.random() * 16;
if (timestamp > 0) {
random = (timestamp + random) % 16 | 0;
timestamp = Math.floor(timestamp / 16);
} else {
random = (perforNow + random) % 16 | 0;
perforNow = Math.floor(perforNow / 16);
}
return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16);
});
};
引入:import {getUuid} from "./assets/getUUID"
修改点击事件:
chart.on('click',(event:any)=>{
// console.log(city)
// console.log(event)
event.data.source.children.map((child:any)=>{
child['index']= getUuid()
})
store.childrenList = event.data.source.children
// console.log(store.childrenList)
})
html:
<transition-group enter-active-class="animate__animated animate__backInRight" tag="tbody">
<tr v-for="(item) in store.childrenList" :key="item.index">
<td>{{item.name}}td>
<td>{{item.total.confirm}}td>
<td>{{item.today.confirm}}td>
<td>{{item.today.local_confirm_add}}td>
tr>
transition-group>
其他图表实现原理一样,因此就不展示了,走了一遍流程。
源代码