node联合echarts简单实现疫情地图

基本步骤:

  1. node爬取数据
  2. 获取标准数据
  3. 前台数据标准化
  4. 展示

效果展示:
node联合echarts简单实现疫情地图_第1张图片

利用node爬取数据

爬取网站:丁香网
所要使用的node第三方模块 01 superagent用于向目标网站发送请求并带回数据。 02 cheerio可将返回的数据转为Jq的DOM树。方便操作数据

利用superagent向目标网站发送请求。(ps:superagent为promise对象)
先让我们来看看它带回来的是个什么玩意儿。

superagent.get("https://ncov.dxy.cn/ncovh5/view/pneumonia").then(res => {
     
	console.log(res);
})


密密麻麻的有些让人头大是不是,可是你仔细看一下便能发现规律。它返回的是一个个html标签夹带的数据。并且其分类很清楚。
node联合echarts简单实现疫情地图_第2张图片
看我们这里所需要的数据,它被包含在id为getAreaStat的这个script标签里面。我们所要用的具体数据在名为window.getAreaStat的这个数组里面。但是在node里面是没有window标签。所以这里我们要处理一下。用另一个字符代替这个window。

cheerio模块的强大之处便可在这里体现出来。

这里我将取出的所需数据利用fs模块写入了一个文档里面,方便一会传给前台
superagent.get("https://ncov.dxy.cn/ncovh5/view/pneumonia").then(res => {
     
    const $ = cheerio.load(res.text);

    let $getAreaStat = $("#getAreaStat").html();
    let obj = {
     };
    let newGetAreaStat = $getAreaStat.replace(/window/g, "obj");
    eval(newGetAreaStat);
    //eval函数可将字符串参数作为js语句执行,这里执行完的结果是给obj添加了一个属性,属性值就是我们所需的数据
    fs.writeFile(path.join(__dirname, "data.txt"), JSON.stringify(obj), err => {
     
        if (err == null) {
     
            console.log("写入成功");

        } else {
     
            throw err;
        }
    });

})

创建服务器,设置响应数据

这里比较常规,就不做解释了

代码:

const express = require("express");
const fs = require("fs");
const path = require("path");
const cors = require("cors");
const app = express();
app.use(cors());

app.get("/index", (req, res) => {
     
    fs.readFile(path.join(__dirname, "data.txt"), "utf8", (err, doc) => {
     
        res.send(doc);
    });

});


app.listen(3000);
console.log("服务启动成功");

访问此路由查看:
node联合echarts简单实现疫情地图_第3张图片

前台展示,借助echarts

首先当然是要引入echarts所依赖的js文件。(去echarts官网拿一个便ok)
基本配置:

//准备一个容器
<div id="main" style="width: 600px;height:400px;"></div>
//初始化
let myChart = echarts.init(document.querySelector("#main"));
//相关配置
            myChart.setOption({
     
            //配置标题信息
                title: {
     
                    text: '全国新冠疫情分布情况',
                    left: 'center'
                },
	
			//配置鼠标经过展示信息
                tooltip: {
     
                    formatter: params => {
     

                        return `地区:${
       params.name}
现存确诊:
${ params.value }人>`
} }, //配置人数区间颜色等信息 visualMap: [{ type: 'piecewise', // continuous连续的 piecewise分段 pieces: [{ gt: 10000 }, // (10000, Infinity] { gt: 1000, lte: 9999 }, // (1000, 9999] { gt: 100, lte: 999 }, // (100, 999] { gt: 10, lte: 99 }, // (10, 99] { gt: 0, lte: 9 } // (0, 9] ], inRange: { color: ['#fdebcf', '#f59e83', '#e55a4e', '#cb2a2f', '#811c24'] } }], //配置图表类型,以及数据 series: [{ type: "map", map: "china", label: { // 覆盖物设置 show: true }, data: data }] })

注意其中的data的类型是有标准的。它必须是这样的类型

[{
     name: '湖北', value: 5556},{
     name:"北京",value:"55"}...]

而刚才我们在服务器准备的数据格式显然不符合此标准。所以需要进行处理。
这里我使用Ajax进行请求数据。

 var xhr = new XMLHttpRequest();
        xhr.open('get', 'http://localhost:3000/index');
        xhr.send();
        xhr.onload = function() {
     
            var data = [];
            //服务器与浏览器之间的数据是以字符串格式相关传递的
            var responseText = JSON.parse(xhr.responseText);
            //用刚刚声明的新数组,把里面的对象格式转换为我们所需要的形式
            responseText.getAreaStat.forEach(ele => {
     
                data.push({
     
                    name: ele.provinceShortName,
                    value: ele.currentConfirmedCount,
                    curedCount: ele.curedCount,
                    deadCount: ele.deadCount
                });

            });
            }

所有工作到这来已经全部完成

代码

前台所有代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="js/echarts.min.js">
    </script>
    <script src="js/china.js"></script>
</head>

<body>

    <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>

    <script>
        let myChart = echarts.init(document.querySelector("#main"));
        // 指定图表的配置项和数据
        let newData = [];
        var newArr;

        var xhr = new XMLHttpRequest();
        xhr.open('get', 'http://localhost:3000/index');
        xhr.send();
        xhr.onload = function() {
     
            var data = [];
            var responseText = JSON.parse(xhr.responseText);
            responseText.getAreaStat.forEach(ele => {
     
                data.push({
     
                    name: ele.provinceShortName,
                    value: ele.currentConfirmedCount,
                    curedCount: ele.curedCount,
                    deadCount: ele.deadCount
                });

            });


            myChart.setOption({
     
                title: {
     
                    text: '全国新冠疫情分布情况',
                    left: 'center'
                },

                tooltip: {
     
                    formatter: params => {
     

                        return `地区:${
       params.name}
现存确诊:
${ params.value }
治愈:
${ (params.data.curedCount ) || 0}
死亡:
${ params.data.deadCount||0}
`
} }, visualMap: [{ type: 'piecewise', // continuous连续的 piecewise分段 pieces: [{ gt: 10000 }, // (10000, Infinity] { gt: 1000, lte: 9999 }, // (1000, 9999] { gt: 100, lte: 999 }, // (100, 999] { gt: 10, lte: 99 }, // (10, 99] { gt: 0, lte: 9 } // (0, 9] ], inRange: { color: ['#fdebcf', '#f59e83', '#e55a4e', '#cb2a2f', '#811c24'] } }], series: [{ type: "map", map: "china", label: { // 覆盖物设置 show: true }, data: data }] }) } </script> </body> </html>

后台所有代码:

  • spider.js

const superagent = require("superagent");
const cheerio = require("cheerio");
const fs = require("fs");
const path = require("path");

superagent.get("https://ncov.dxy.cn/ncovh5/view/pneumonia").then(res => {
     
    const $ = cheerio.load(res.text);

    let $getAreaStat = $("#getAreaStat").html();
    let obj = {
     };
    let newGetAreaStat = $getAreaStat.replace(/window/g, "obj");
    eval(newGetAreaStat);
    fs.writeFile(path.join(__dirname, "data.txt"), JSON.stringify(obj), err => {
     
        if (err == null) {
     
            console.log("写入成功");

        } else {
     
            throw err;
        }
    });

 
})
  • 服务器 app.js
const express = require("express");
const fs = require("fs");
const path = require("path");
const cors = require("cors");
const app = express();
app.use(cors());

app.get("/index", (req, res) => {
     
    fs.readFile(path.join(__dirname, "data.txt"), "utf8", (err, doc) => {
     
        res.send(doc);
    });

});


app.listen(3000);
console.log("服务启动成功");

你可能感兴趣的:(node,#,node案例,nodejs,js)