前言

此系列已完结,共3部分:

  • part1:https://blog.csdn.net/xi1213/article/details/126824752
  • part2:https://blog.csdn.net/xi1213/article/details/127719364
  • part3:https://blog.csdn.net/xi1213/article/details/128072446

自成都九月份以来疫情原因被封了一两周,居家着实无聊,每天都是盯着微信公众号发布的疫情数据看,那种页面,就我一个前端仔来说,看着是真的丑啊!(⊙_⊙)?既然丑,那就自己动手开整!项目是2022.9.5开始的,截止2022.9.12我完成了大概有八成。主要是想让数据更加直观,而且可离线下载(当然还有装逼!┑( ̄Д  ̄)┍)。

项目描述

为证明是有料的,先看效果图(提前装逼!┗|`O′|┛ 嗷~~):




项目我是公开了的( ̄m ̄)有兴趣的可以下下来玩玩,这是我第一次使用vue3+ts构建项目,肯定还有不足的地方(比如ts中疯狂的:any,一直any一直爽^o^/)。
这里是浏览链接:http://xisite.top/original/covid19-visualization/index.html#/
这里是项目链接:https://gitee.com/xi1213/covid19-visualization
(欢迎star!欢迎star!欢迎star!(●’◡’●)嘿嘿嘿~)
项目中使用到的技术有:vue3、TypeScript、Three.js、Echarts、elementPlus。

项目目标

1、以为3D形式展示全球疫情分布。
2、显示实时疫情数值。
3、以图表形式分析疫情数据。
4、允许下载各地疫情excel表格。
5、自动获取用户位置。
6、分析当地疫情数据。
7、生成当地疫情word报告。

api说明

本项目数据来源:新浪公共疫情api(新浪的数据来源于国家卫健委、各省市区卫健委、各省市区政府、港澳台官方渠道等公开数据。这也是够权威官方了)。我主要使用了两个新浪的api和一个太平洋网络ip地址查询web接口。
1、https://news.sina.com.cn/project/fymap/ncp2020_full_data.json
get方式,无入参。该api可获取全球各国大致疫情数据,以及国内的详情疫情数据,这里就api中的字段做一下说明,字段是我自己推测出来的含义,不会100%全而准(→_→):

{"add_daily(国内今日数据)": {"addcon(今日确诊新增数)": "","addcure(今日治愈新增)": "","adddeath(今日死亡新增)": "","addjwsr(今日境外输入新增)": "","addlocIncrNum(今日本土新增)"},"cachetime(数据缓存时间)": "","curetotal(国内治愈总数)": "","deathtotal(国内死亡总数)": "","gntotal(国内确诊总数)": "","highAndMiddle(中高风险地列表)": [{"allname(全名)": "","list(城市列表)": "","province(省名)": "","province_high_areas(高风险区域)": "","province_middle_areas(中风险区域)": "","province_high_num(高风险区域数)": "","province_middle_num(中风险区域数)": "","province_total(风险地总数)": ""}],"historylist(国内疫情历史数据)": [{"cn_conNum(确诊总数)": "","cn_cureNum(治愈总数)": "","cn_deathNum(死亡数)": "","cn_jwsrNum(境外输入)": "","ymd(当前时间)": ""}],"jwsrTop(境外数据前10列表)": [],"list(全国各省疫情数据列表)": [{"asymptomNum(较昨日新增数)": "","city(城市列表)": [],"cureNum(治愈数)": "","deathNum(死亡数)": "","econNum(现存确诊数)": "","ename(英文省名)": "","jwsrNum(境外输入数)": "","name(省名)": "","value(累计数)": ""}],"locIncrProTop(本土新增前十列表)": [],"othertotal(其他总数)": {"certain(全球现存确诊)": "","certain_inc(今日确诊新增数)": "","die(全球死亡数)": "","die_inc(死亡新增数)": "","ecertain(全球治愈数)": "","ecertain_inc(治愈新增数)": ""},"times(数据截止时间)": "","worldlist(世界各国疫情列表)": [{"name(国名)": "","value(累计数)": "","econNum(确诊数)": "","deathNum(死亡数)": "","cureNum(治愈数)": ""}]
}

2、https://gwpre.sina.cn/interface/news/ncp/data.d.json
get方式,入参:

{mod:"province",province(英文省名):""
}

该api可获取国内指定省份的疫情数据,字段我就不推断了,可自行根据上一个api和部分英文单词大概推断出来(没错!就是我不想打字了!太累了!ಥ_ಥ其实这还不算折磨人的,后面使用api的时候那才叫个曲折)。
3、https://whois.pconline.com.cn/ipJson.jsp
get方式,无入参。该api可获取使用者ip地址、省份、城市。返回结果如下:

数据使用

刚开始开发的时候,我跟以前项目开发一样,跨域嘛,直接整个vue代理(不会vue代理模式的看这儿:https://blog.csdn.net/xi1213/article/details/125950052)不就完事儿了,果然,数据一经过代理,回来是回来了,但汉字全是\n什么什么鬼?乱码?费了一番功夫查了下,不是乱码,是unicode解码的问题。然后我又整了个解码的方法:

//解码返回的unicode
function decodingStr(str: any) {let repStr: any = str.replace(/\\/g, "%");//用%替换\let str1 = repStr.split("jsoncallback(")[1]let str2 = str1.split(");")[0]//截取出需要的字符串let unStr = unescape(str2);//解码出汉字let jsonObj = JSON.parse(unStr);//转换成json对象return jsonObj;
};

这下应该可以了吧?一切很顺利,开发差不多了,npm run build、git add . 、git commit -m""、git push,行云流水!直接上gitee Pages部署发布,完成!打开页面一看?嗯?f12。404?直到后面我又在网上扒拉后才明白,vue的代理在打包成dist后会被抽离失效,在gitee Pages中是不能使用vue的代理模式获取数据的!接下来就是各种尝试跨域,直到看到跨域两个字人都麻了。最后发现不同域下,使用jsonp的方式来处理跨域最为简单,jsonp原理和使用方法在这里:https://blog.csdn.net/xi1213/article/details/126827525?spm=1001.2014.3001.5502

项目开始

项目是vue3的,首先你得创建啊。这里建议使用vue脚手架的图形化界面创建项目,命令为:vue ui
选择手动配置:

打开TypeScript支持:

选择vue3选项:

安装依赖

1、npm install echarts@4.9.0(安装echarts的指定版本,因为项目中需要使用中国地图,在4.9.0之后echarts官方移除了地图支持,之后的版本需要下载chain.js,还得手动下载引入一遍,麻烦,这里直接用老版本)
2、npm i element-plus(vue3对应的element-ui就是element-plus,这是官方使用文档:https://element-plus.gitee.io/zh-CN/guide/design.html )
3、npm i three(看见首页那个大地球了吧?没错,它就是three.js做的,感兴趣的可以看这儿,我以前做的太阳系:https://blog.csdn.net/xi1213/article/details/125726054?spm=1001.2014.3001.5502
4、npm i xlsx(这个是下载excel表格的必备插件,具体使用方法看这里:https://blog.csdn.net/xi1213/article/details/126216054?spm=1001.2014.3001.5502 )

首页球体

1、创建宇宙(叼不叼!是不是感觉自己就是创世主!( ̄_, ̄ )):初始化场景时一定记得设置alpha: true。这里创建宇宙我使用了我以前这篇文章创建背景的第三种方法:https://blog.csdn.net/xi1213/article/details/123244316?spm=1001.2014.3001.5502

import * as THREE from "three";//初始化球体
function init(data: any) {dom = document.getElementById("sphereDiv"); //获取domlet width = dom.clientWidth;let height = dom.clientHeight;scene = new THREE.Scene(); //场景场景camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); //创建透视相机(视场、长宽比、近面、远面)camera.position.set(0, 0, 270); //设置相机位置camera.lookAt(0, 0, 0);//创建渲染器renderer = new THREE.WebGLRenderer({antialias: true, //抗锯齿alpha: true, //透明});renderer.setClearColor(0x000000, 0.1); //设置场景透明度renderer.setSize(width, height); //设置渲染区域尺寸dom.appendChild(renderer.domElement); //将渲染器添加到dom中形成canvascreateUniverse(); //创建宇宙createStars(); //创建星辰createLight(); //创建光源createSphere(data); //创建球体createOrbitControls();render();
};//创建宇宙(球形宇宙)
function createUniverse() {let universeGeometry = new THREE.SphereGeometry(500, 100, 100);let universeMaterial = new THREE.MeshLambertMaterial({//高光材质map: new THREE.TextureLoader().load(universeImg),side: THREE.DoubleSide, //双面显示});//宇宙网格let universeMesh = new THREE.Mesh(universeGeometry, universeMaterial);universeMesh.name = "宇宙";scene.add(universeMesh);
};

2、创建光源:为了效果,我使用了环境光与平行光源,这两种光都会影响贴图原本颜色,建议光源颜色设置为白色。

//创建光源
function createLight() {let lightColor = new THREE.Color(0xffffff);let ambient = new THREE.AmbientLight(lightColor); //环境光ambient.name = "环境光";scene.add(ambient);let directionalLight1 = new THREE.DirectionalLight(lightColor);directionalLight1.position.set(0, 0, 1000);scene.add(directionalLight1); //平行光源添加到场景中let directionalLight2 = new THREE.DirectionalLight(lightColor);directionalLight2.position.set(0, 0, -1000);scene.add(directionalLight2); //平行光源添加到场景中let directionalLight3 = new THREE.DirectionalLight(lightColor);directionalLight3.position.set(1000, 0, 0);scene.add(directionalLight3); //平行光源添加到场景中let directionalLight4 = new THREE.DirectionalLight(lightColor);directionalLight4.position.set(-1000, 0, 0);scene.add(directionalLight4); //平行光源添加到场景中let directionalLight5 = new THREE.DirectionalLight(lightColor);directionalLight5.position.set(0, 1000, 0);scene.add(directionalLight5); //平行光源添加到场景中let directionalLight6 = new THREE.DirectionalLight(lightColor);directionalLight6.position.set(0, -1000, 0);scene.add(directionalLight6); //平行光源添加到场景中
};

3、创建球体:

//创建球体
function createSphere(data: any) {let earthSize = 100; //地球尺寸let earthGroup = new THREE.Group(); //地球的组let earthGeometry = new THREE.SphereGeometry(earthSize, 100, 100); //地球几何体let nightColor = new THREE.Color(0x999999);let dayColor = new THREE.Color(0x444444);//地球材质let earthMaterial = new THREE.MeshPhongMaterial({map: new THREE.TextureLoader().load(isDay ? earthImg : earthNightImg //区分昼夜纹理),color: isDay ? dayColor : nightColor,// metalness: 1, //生锈的金属外观(MeshStandardMaterial材质时使用)// roughness: 0.5, // 材料的粗糙程度(MeshStandardMaterial材质时使用)normalScale: new THREE.Vector2(0, 5), //凹凸深度normalMap: new THREE.TextureLoader().load(normalImg), //法线贴图});let earthMesh = new THREE.Mesh(earthGeometry, earthMaterial); //地球网格earthMesh.name = "地球";earthGroup.add(earthMesh); //将地球网格添加到地球组中earthGroup.name = "地球组";scene.add(earthGroup);createVirus(data, earthSize); //创建球面病毒
};


放大项目中的地球你会发现球体表面是有凹凸而且反光的(就像稀泥巴一样≡(▔﹏▔)≡),这是因为使用了three中MeshPhongMaterial材质同时设置了属性normalScale与normalMap。

4、渲染:创建完成后记得渲染,否则是不会生效的。

//渲染
function render() {anId.value = requestAnimationFrame(render);document.getElementById("sphereDiv") &&document.getElementById("sphereDiv")!.addEventListener("mousemove", onMousemove, false);orbitControls.update(); //鼠标控件实时更新renderer.render(scene, camera);
};

控制球体

首页的3D球体是可以进行鼠标控制的。

这是使用的three.js自带的鼠标控件OrbitControls ,它的参数可以自己设置,这是鼠标控制的方法:

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";//创建鼠标控件
function createOrbitControls() {orbitControls = new OrbitControls(camera, renderer.domElement);orbitControls.enablePan = false; //右键平移拖拽orbitControls.enableZoom = true; //鼠标缩放orbitControls.enableDamping = true; //滑动阻尼orbitControls.dampingFactor = 0.05; //(默认.25)orbitControls.minDistance = 150; //相机距离目标最小距离orbitControls.maxDistance = 500; //相机距离目标最大距离orbitControls.autoRotate = true; //自转(相机)orbitControls.autoRotateSpeed = 1; //自转速度orbitControls.enableRotate = true;//鼠标左键控制旋转
};

创建病毒

被瞎说!covid19可不是我创造的!(;´д`)ゞ

//创建病毒
function createVirus(data: any, earthSize: any) {let colors = [new THREE.Color(0xf9b8b8),new THREE.Color(0xfe4242),new THREE.Color(0xff0000),]; //病毒颜色列表let virSize = 4; //病毒大小let pointsGroup = new THREE.Group(); //点的组let list = JSON.parse(JSON.stringify(data));list.forEach((e: { value: number; color: any; position: any[]; }) => {e.value >= 10000000 && (e.color = colors[2]); //根据病毒数赋予不同颜色e.value >= 500000 && e.value < 10000000 && (e.color = colors[1]);e.value < 500000 && (e.color = colors[0]);if (e.position) {let virusMaterial = new THREE.SpriteMaterial({color: e.color,map: new THREE.TextureLoader().load(virusImg),side: THREE.FrontSide, //只显示前面}); //病毒材质let Sprite = new THREE.Sprite(virusMaterial); //点精灵材质Sprite.scale.set(virSize, virSize, 1); //点大小let lat = e.position[1]; //纬度let lon = e.position[0]; //经度let s = latLongToVector3(lat, lon, earthSize, 1); //坐标转换Sprite.position.set(s.x, s.y, s.z); //设置点的位置Sprite.dotData = e; //将点的数据添加到dotData属性中Sprite.name = "病毒";pointsGroup.add(Sprite); //添加进点的组中}});pointsGroup.name = "病毒组";scene.add(pointsGroup); //点的组添加到旋转组中
};

球面上那些红的、粉的、白的玩意儿就是病毒。其实就是利用three的SpriteMaterial材质加入点精灵Sprite中,再遍历病毒的坐标列表数据,循环设置Sprite的position属性,最后再将创建好的病毒组添加到宇宙场景中,值得注意的是,你一般获取到的数据均为经纬度坐标,需要转换为three能用的三维向量坐标,这是坐标转换的方法:

//经纬度坐标变换(传入e:纬度、a经度、t球半径、o球额外距离)
function latLongToVector3(e: any, a: any, t: any, o: any) {var r = (e * Math.PI) / 180,i = ((a - 180) * Math.PI) / 180,n = -(t + o) * Math.cos(r) * Math.cos(i),s = (t + o) * Math.sin(r),l = (t + o) * Math.cos(r) * Math.sin(i);return new THREE.Vector3(n, s, l); //计算三维向量
};

数值增加动画

在首页右侧和“国内分析”右侧,有一排数字,那个数字在加载时是有数值增加动画的。

本来想直接使用vue-count-to或者vue-countupjs的,但网上我扒拉了一下,发现原理好像不是很难,无非就是利用vue的数据响应式原理,但我看到的大多封装的组件都是vue2的,vue3好像没有。这里我就整一个vue3+ts的版本:

<template><span :data-time="time" :data-value="value">{{addNum}}</span>
</template><script lang='ts' setup>
import { ref, computed, watch, onMounted } from 'vue';
let props = defineProps({//动画时间time: {type: Number,default: 2},//停止时的值value: {type: Number,default: 0},//千位的逗号thousandSign: {type: Boolean,default: () => false}
}),oldValue: any = ref(0),addNum: any = ref(0);//响应式的数值watch(() => props.value,() => {startAnimation();//值改变时开始动画})function startAnimation() {let value: number = props.value - oldValue.value;let step = (value * 10) / (props.time * 100);let current = 0;let start = oldValue.value;//定时器let t: any = setInterval(() => {start += step;if (start > value) {clearInterval(t);start = value;t = null;}if (current === start) {return;}current = Math.floor(start);//取整oldValue.value = current;if (props.thousandSign) {addNum.value = current.toString().replace(/(\d)(?=(?:\d{3}[+]?)+$)/g, '$1,');//添加千位符} else {addNum.value = current.toString();//无千位符}}, 10)
}onMounted(() => {startAnimation();
})
</script>

value是动画终止时数值,time是动画时间,thousandSign表示是否添加千分位符,必须保证value与time类型为Number,这是使用方法:

<addNumber class="addcure-div" :value="addcure" :time="10" :thousandSign="true" />

表格展示

页面上的所有表格都是使用的element-plus的表格组件,这是具体使用方法:https://element-plus.gitee.io/zh-CN/component/table.html
当表格做出来之后发现样式颜色之类的并不是自己想要的。其实可以更改css变量。注意,不是全局修改,是局部修改样式。比如你想让表格变成这样透明的:

那么你可以这样做:

<el-table :data="tabData" style="width: 100%;height: calc(100vh - 100px);--el-table-bg-color:rgba(0,0,0,.8);--el-table-tr-bg-color:transparent;--el-table-header-bg-color:#333;--el-table-header-text-color:#fff;--el-table-text-color:#fff;--el-table-row-hover-bg-color:#333;--el-table-border-color:#333"><el-table-column type="index" label="序号" width="100" /><el-table-column prop="name" label="国家" /><el-table-column prop="value" label="累计数" sortable /><el-table-column prop="deathNum" label="死亡数" sortable /><el-table-column prop="cureNum" label="治愈数" sortable /><el-table-column prop="citycode" label="地区代码" /><el-table-column label="坐标"><template #default="scope">{{ scope.row.position ? scope.row.position : "-" }}</template></el-table-column></el-table>

其中的css变量名,你可以f12获取到。

横向柱状图

首页左侧和“国内分析”这样的横向柱状图。

在echarts里面配置项是这样的:

//柱状图数据let option: any = {title: {text: titName + sliceNum,left: "center",textStyle: {color: "#fff",},},tooltip: {backgroundColor: "rgba(0,0,0,.5)",borderWidth: "0",trigger: 'axis',textStyle: {color: "#fff",fontWeight: "bolder"},},grid: {top: "10%",left: "10%",right: "10%",bottom: "0%",},xAxis: {type: 'value',show: false,},yAxis: {type: 'category',axisLabel: {color: "#fff",},data: [],},series: [{data: [],type: 'bar',showBackground: true,backgroundStyle: {color: 'rgba(180, 180, 180, 0.2)'},itemStyle: {color: color,},label: {color: "#fff",fontWeight: "bolder",show: true,align: "left",formatter: "{c}",},}]}

颜色、位置、标题可自己设置。

中国地图

在“国内分析”中有一个中国地图,用来展示国内现存确诊分布,支持缩放拖拽。

如果你下载的最新的echarts的话,那么你得折腾下,自己另外单独找chain.js下载,然后引入项目,4.9.0是内置地图的,可以直接使用。这是地图的配置项:

  let option: any = {title: {text: '国内各省现存分布',left: "center",top: '1%',textStyle: {color: "#fff",},},visualMap: {min: 0,max: 500,left: '5%',bottom: '5%',text: ['高', '低'],textStyle: {color: '#fff',},calculable: true,inRange: {color: ['#fff', '#f00'],//颜色范围},},tooltip: {padding: 10,enterable: true,transitionDuration: 0,//动画时间backgroundColor: "rgb(0,0,0,.8)",borderRadius: 20,textStyle: {color: '#fff',},formatter: function (params: any) {let tipString = "";if (params.data.value) {tipString ="<div style='font-size:25px;font-weight:900;margin:10px 0px'>" + params.data.name + "</div>" +"<div style='color:#f00;font-weight:900;'>现存:" + params.data.value + "</div>" +"<div style='color:#888;font-weight:900;'>累计:" + params.data.allNum + "</div>" +"<div style='color:#888;font-weight:900;'>死亡:" + params.data.deathNum + "</div>" +"<div style='color:#888;font-weight:900;'>治愈:" + params.data.cureNum + "</div>" +"<div style='color:#888;font-weight:900;'>较昨日新增:" + params.data.asymptomNum + "</div>" +"<div style='color:#888;font-weight:900;'>境外输入:" + params.data.jwsrNum + "</div>"}return tipString;}},series: [{name: '接入医院数量',type: 'map',mapType: 'china',zoom: 1.2,//缩放roam: true,scaleLimit: {min: 1.2,//缩放限制max: 2},itemStyle: {normal: {label: {show: true}},emphasis: {show: true,areaColor: '#6eb5ff',//鼠标滑过区域颜色label: {show: true}}},label: {normal: { //静态的时候展示样式show: true, //是否显示地图省份得名称textStyle: {color: "#000",fontSize: 12}},emphasis: { //动态展示的样式color: '#fff',},},data: []}]};

formatter也就是hover出来的信息框,可以自定义。

历史分析

“国内分析”是有个历史数据展示的折线图的,它是允许缩放调节的。

这是它的echarts配置项:

  let option: any = {// backgroundColor: "",grid: {// top: "15%",// left: "5%",// right: "5%",// bottom: "10%",},title: {text: '国内历史数据',left: "center",top: '5%',textStyle: {color: "#fff",},},tooltip: {backgroundColor: "rgba(0,0,0,.5)",borderWidth: "0",trigger: 'axis',textStyle: {color: "#fff",fontWeight: "bolder"},axisPointer: {type: 'cross'},},legend: {data: ['确诊数', '治愈数', '死亡数', '境外输入'],textStyle: {color: "#fff"},orient: "vertical",top: "15%",right: "2%"},xAxis: {data: lineData.map(function (item: any) {return item.ymd;}),textStyle: {color: "#fff"}},yAxis: {textStyle: {color: "#fff",},},dataZoom: [{startValue: ''},{type: 'inside'}],series: [{name: '确诊数',type: 'line',lineStyle: {color: '#f4c25e'},itemStyle: {color: '#f4c25e'},data: lineData.map(function (item: any) {return item.cn_conNum;}),zlevel: 1,z: 1,},{name: '治愈数',type: 'line',lineStyle: {color: '#48c56b'},itemStyle: {color: '#48c56b'},data: lineData.map(function (item: any) {return item.cn_cureNum;}),zlevel: 1,z: 1,},{name: '死亡数',type: 'line',lineStyle: {color: '#f00'},itemStyle: {color: '#f00'},data: lineData.map(function (item: any) {return item.cn_deathNum;}),zlevel: 1,z: 1},{name: '境外输入',type: 'line',lineStyle: {color: '#8903ba'},itemStyle: {color: '#8903ba'},data: lineData.map(function (item: any) {return item.cn_jwsrNum;}),zlevel: 1,z: 1}]};

表格下载

主要是利用xlsx插件,好用得很,直接传入数据就出表格了,这是我的使用方法:

import * as XLSX from "xlsx";//入参示例
let eg = {fileName: "测试",//文件名tabHead: ["国家", "人口", "测试"],//表头列表keyList: ["name", "population", "test"],//表头对应的属性名,顺序必须与表头对应tabData: [{ name: "中国", population: "11", test: "t1" },{ name: "美国", population: "22", test: "t2" },{ name: "日本", population: "35", test: "t3" }]//对象数组
}//导出数据表格
export default async function downloadXlsx(tabObj: any) {let aoaList: any = [];aoaList[0] = tabObj.tabHead; //赋值表头列表tabObj.tabData.forEach((tabItem: any, tabIndex: number) => {aoaList[tabIndex + 1] = [];//该二维度数组必须多加一个元素,因为表头占第一个元素tabObj.keyList.forEach((keyItem: any, keyIndex: number) => {let val = tabItem[keyItem];//获取表格属性的值((typeof val == "undefined") || (val == "")) ?(aoaList[tabIndex + 1][keyIndex] = "-") ://数据未定义或者为空则用"-"代替(aoaList[tabIndex + 1][keyIndex] = val + "");//添加空字符串,防类型为非字符串})});let workSheet = null;workSheet = XLSX.utils.aoa_to_sheet(aoaList); //将列表数据添加到工作表let workBook = XLSX.utils.book_new(); //创建一个工作薄XLSX.utils.book_append_sheet(workBook, workSheet, "1"); //将工作表添加到工作薄中await XLSX.writeFile(workBook, tabObj.fileName + ".xlsx"); //写入文件,下载工作薄
};

结语

我做这个其实还是学到了很多东西,主要是vue2与vue3的区别。以前的this算是可以彻底抛弃了,还有就是组合式api配合setup语法糖,爽啊!就连组件引入后都不用注册了,直接使用。不过也有注意点,用ref()声明的响应式变量使用时需要加.vaule。至于ts,我感觉自己还是很菜啊,一直any一直爽。。。。。。ts类型系统直接被我无视了,后面还得观摩观摩其他大佬咋写的。截止到现在2022.9.13成都疫情好转要复工了,项目其实都是没有完成的,主要还差“省内分析”和“下载当地疫情报告”,我做了alert提示,反正数据获取到了,后面在搞,我项目是完全开源了的,有牛逼的可以直接clone下来开发完成(我想要白嫖!(╯▔皿▔)╯)。


这篇文章我只在csdn和博客园发布过,最后还有句话,我知道某些人,某些网站,会直接把我文章扒过去,我不是不允许你们扒,你们至少得留个原作者和来源吧?!(ノ`Д)ノ(ノ`Д)ノ(ノ`Д)ノ

疫情可视化part1相关推荐

  1. 记录自己三天速成django+html制作国内疫情可视化平台的过程(二)

    3.可视化页面 3.1设计 经过(一)中的操作,我们已经将登录/注册的功能基本实现.下面就是设计可视化页面了,一共会画8张图,我初步的设计是这样的: {% load static %} <!DO ...

  2. 大数据疫情可视化平台1_基于Hadoop3.2.1、Hive3.1.2、搭建疫情信息可视化系统

    前言 项目效果展示 项目源码免费获得请私信博主,绝对免费! 目录 Linux基础命令:往期博客Linux课堂篇3_Linux目录结构.快捷键.常用基础命令 Hadoop3.2.1介绍与环境搭建 Hiv ...

  3. 【实战篇】39 # 如何实现世界地图的新冠肺炎疫情可视化?

    说明 [跟月影学可视化]学习笔记. 世界地图新冠肺炎疫情可视化 下面将实现世界地图新冠肺炎疫情可视化.数据用的是从 2020 年 1 月 22 日到 3 月 19 日这些天的新冠肺炎疫情进展.效果类似 ...

  4. python爬虫疫情可视化

    学习了pyecharts后来小试牛刀下,来做一个中国疫情可视化 首先安装pyecharts库 1.可以直接在pycharm上装 2.也可以更快命令行装,win+r cmd pip install -i ...

  5. 全球疫情可视化实时更新

    全球疫情可视化实时更新 1. 配置 boostrap为前端框架,echarts可视化,jQuery获取.处理数据 2. 思路 前端框架搭好,这里不细说 后端用JQuery从API中获取数据 3. 如何 ...

  6. 数据可视化之疫情可视化

    一 前言 新型冠状病毒肺炎(COVID-19,简称"新冠肺炎")疫情肆虐全球多个国家,2020年3月11日,世界卫生组织 (WHO) 正式宣布将新冠肺炎列为全球性大流行病. 在全球 ...

  7. 基于Springboot的新冠疫情可视化管理系统(可视化展示+后台管理功能)

    这里写自定义目录标题 基于Springboot的新冠疫情可视化管理系统 基础环境: 功能快捷键 实现效果图 源码查看 基于Springboot的新冠疫情可视化管理系统 本项目有基于Springboot ...

  8. Python新冠疫情可视化分析系统 计算机专业毕业设计源码08504

    摘 要 文中首先对新冠疫情可视化分析的项目需求进行了背景分析,接着介绍了项目的总体设计思路,然后具体阐述了疫情数据库的设计.疫情数据的查询.疫情数据的展示,并分析了核心代码.文中利用MySQL数据库存 ...

  9. 疫情数据可视化-湖北省疫情可视化软件设计大赛作品

    湖北省疫情监测中心(疫情数据可视化)目录 前言 一.数据可视化 二.疫情可视化 湖北省疫情监测中心 ① 主要框架 ② 数据爬取 ③ 疫情可视化模块(疫情监测模块) ④ 便民信息可视化模块(检测信息模块 ...

最新文章

  1. try-catch-finally中的4个巨坑,老程序员也搞不定!
  2. Java Swing Awt
  3. C++调用python(C++)
  4. 用C语言写的迅雷看看XV文件提取器及C语言源代码
  5. linux下安装gcc
  6. 项目需求:基于微信平台的拼团活动系统
  7. 一道曾经微软的面试题
  8. GitHub 又一 OCR 神器面世!让你快速告别「复制 + 粘贴」!
  9. 例2.8 叠筐 - 九度教程第15题(排版题)
  10. Keil V4安装教程
  11. 战旗助手服务器代码,炉石传说酒馆战旗助手
  12. 如何用计算机ip连接打印机共享,ip共享打印机怎么设置
  13. MVVM框架原理浅析
  14. java中1字节(8位)_Java中基本数据类型占几个字节多少位
  15. (小脚本) (python) 批量修改文件后缀名
  16. Windows10 64位系统设置FRPC开机自动启动
  17. Python 函数 | zip 函数详解
  18. Docker容器获取局域网ip(使用macvlan)
  19. unzip解压缩linux文件时出现error [Testing.zip]: start of central directory not found;zipfile corrupt——7z
  20. Nginx HTTP 健康检查

热门文章

  1. spark-2.2.0发行说明
  2. 按键精灵--多点找形状介绍
  3. Scratch编程-画图模块13【寿光市青少年创意编程大赛真题】
  4. python实现中撤销上一步的代码mac_苹果电脑command+z撤销后如何恢复撤销前的上一步?...
  5. 单片机驱动SD3077时钟芯片
  6. 优质的客户期货开户交易所返还高
  7. 二叉树的层次遍历 II - LeetCode
  8. MD5加密——原理介绍
  9. 2018年EI收录中文期刊目录【转】
  10. FRW辐轮王全球十大顶级运动户外品牌第一自行车受邀中国进博会