node聯合echarts簡單實現疫情地圖

基本步驟:

  1. node爬取數據
  2. 獲取標準數據
  3. 前臺數據標準化
  4. 展示

效果展示:
在這裏插入圖片描述

利用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標籤夾帶的數據。並且其分類很清楚。
在這裏插入圖片描述
看我們這裏所需要的數據,它被包含在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("服務啓動成功");

訪問此路由查看:
在這裏插入圖片描述

前臺展示,藉助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}<br/>現存確診:${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}<br/>現存確診:${params.value }人<br/>治癒:${(params.data.curedCount ) || 0}人<br/>死亡:${params.data.deadCount||0}人<br/>`
                    }
                },
                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("服務啓動成功");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章