使用nodejs和html+css+JavaScript搭建一个网站实现数据可视化

本设计主要使用前端绘图,后端服务器接受数据并且更新发送前端实现绘图更新,前面大部分的东西可以跟着大佬兴趣使然_      看这些

最终效果

 

1.安装环境

下载安装包nodejs

打开命令指示符,输入检查安装好没有

node -v // 显示安装的 nodejs 版本
npm -v     // 显示安装的 npm 版本

 修改全局模块路径和缓存路径;设置路径时,别忘记加双引号;设置完后查看验证.

npm config set prefix "创建的 node_global 文件夹所在路径"//C:\Program Files\nodejs\node_global
npm config set cache "创建的 node_cache 文件夹所在路径"//C:\Program Files\nodejs\node_cache
// 查看验证
npm config get prefix 
npm config get cache

1.1创建工程

我使用的vscode

 https : 存放 https 密钥等文件;
Markdown : 存放 笔记,也就是文档内容;
node_modules : 存放 工程所依赖的 node 模块包;
static/css : 存放 网页样式;
static/image : 存放 网页图片;
static/js : 存放 网页脚步;
template : 存放 网页本体;
WEB_SERIA_API : 存放 以上所有内容,父级目录,工程目录.即 : ./;

1.2写一个简单的网页

在template目录下新建1.html文件,输入感叹号可以快速构建一个模板


       <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
 <!-- 测试 : 图表容器 DOM -->
    <div id="container" style="width: 800px;height:400px;margin: 0 auto;border-style:dashed ; 
    border-width: 5px; "></div>
</body>
</html>

运行结果如下


2.安装express

打开命令指示符

npm install express --save
3.创建https

推荐参考node配置本地https服务

3.1创建服务器

在根目录下创建server.js

代码如下,实际使用中将ip地址换成自己的

// 一个简洁而灵活的 node.js Web应用框架对象中
const express = require('express'); 
const app = express();
let mydata;
let mydata1;

// 访问本地静态文件, __dirname 代表本脚本的路径
app.use('/', express.static(__dirname)); 

// // 启动 http 服务器端
// const httpServer = app.listen(6081, function () 
// {
//     let host1 =  "49.233.249.196"  	// 本机 IPv4 地址
//     let host2 =  "127.0.0.1"  		// 本机 地址
//     let host3 =  "localhost"  		// 本地 服务器
//     let port = httpServer.address().port
// 	// 这里只是在终端输出打印字符
//     console.log("应用实例,访问地址为 http://%s:%s/template/1.html", host1, port)
//     console.log("应用实例,访问地址为 http://%s:%s/template/1.html", host2, port)
//     console.log("应用实例,访问地址为 http://%s:%s/template/1.html", host3, port)
// })
// 启动 https 服务需要 https 包
// 读取文件需要 fs 包
const https = require('https');
const fs = require('fs');

// 将两个证书文件读取放到 options 对象中
// 使用 readFileSync() 方法,顺序地执行 读文件 和 启动服务 操作
const options = 
{
    key: fs.readFileSync('./https/privatekey.pem'), //密钥路径
    cert: fs.readFileSync('./https/certificate.pem')
};

// 创建服务器,使用 express 框架
const httpsServer  = https.createServer(options, app)

// 启动 https 服务器,设置监听端口号
httpsServer.listen(6080, function () 
{
    let host =  "192.168.0.203"  // 本机 IPv4 地址49.233.249.196
    let port = httpsServer.address().port
    console.log("应用实例,访问地址为 https://%s:%s/template/1.html", host, port)
})
// express 处理 get 请求
// app.get('/express_get', function (req, res) 
// {
//     let data= req.query // 取出参数,字典的形式

//     console.log(data) // 在中断打印接收到参数

//     res.send(data) // 页面输出接收到的参数
// })
app.get('/api/data', (req, res) => {
    // 从服务器获取数据
    // const data = getDataFromServer(); // 这里需要根据你的实际情况编写获取数据的逻辑
    // mydata = Array.from({ length: 40 }, (_, i) => i * 0.01) ;
    // console.log("https:",mydata);
    // const data = Array.from({ length: 40 }, (_, i) => i * 0.01) ;
    // 将数据转换为JSON格式并发送回前端
    res.json(mydata);
    // res.mydata;
  });
// express 处理 post 请求

// Express 中默认都使用 body-parser 作为请求体解析 post 数据
const bodyParser = require("body-parser");

// 解析以 application/json 和 application/x-www-form-urlencoded 提交的数据
const jsonParser = bodyParser.json();
const urlencodedParser = bodyParser.urlencoded({ extended: false });
// 全局作用
app.use(jsonParser);
app.use(urlencodedParser);

// req 代表请求对象 res 代表返回对象
app.post('/express_post', function(req,res)
{
    // req: 客户端 携带的信息
    console.log(
    [req.query,         // 打印 get 参数
    req.params,         // 打印 不知道什么
    req.body,           // 打印 post 数据
    req.get('Origin'),  // 打印 网址:端口
    req.url]);          // 打印 端口后面的

    res.send(req.body);     // 返回 get 参数
});
var net = require("net");
var clients = []; // 保存所有已连接的客户端socket
// 创建一个net.Server用来监听,当连接进来的时候,就会调用我们的函数
// client_sock,就是我们的与客户端通讯建立连接配对的socket
// client_sock 就是与客户端通讯的net.Socket
var server = net.createServer(function(client_sock) { 
	console.log("client comming", client_sock.remoteAddress, client_sock.remotePort);
	// 设置你接受的格式, 
  clients.push(client_sock);
	// client_sock.setEncoding("utf8");
	// client_sock.setEncoding("hex"); // 转成二进制的文本编码
	// 
	// 客户端断开连接的时候处理,用户断线离开了
	client_sock.on("close", function() {
		console.log("close socket");
    var index = clients.indexOf(client_sock);
        if (index !== -1) {
            clients.splice(index, 1);
            console.log("close one socket");
        }
	});
 
	// 接收到客户端的数据,调用这个函数
	// data 默认是Buffer对象,如果你强制设置为utf8,那么底层会先转换成utf8的字符串,传给你
	// hex 底层会把这个Buffer对象转成二进制字符串传给你
	// 如果你没有设置任何编码 <Buffer 48 65 6c 6c 6f 57 6f 72 6c 64 21>
	// utf8 --> HelloWorld!!!   hex--> "48656c6c6f576f726c6421"
	client_sock.on("data", function(data) {

    var dividedArray = Array.from(data).map(byte => byte / 256);
    console.log("TCP (Divided Array):", dividedArray);
        // mydata1=data;
        mydata=dividedArray;
    //   clients.forEach(function(sock) {
    //     sock.write(data);
    // });
		// client_sock.end(); // 正常关闭
	});
 
 
	client_sock.on("error", function(err) {
		console.log("error", err);
	});
});
 
// 当我开始监听的时候就会调用这个回掉函数
server.on("listening", function() {
	console.log("start listening...");
});
 
 
// 监听发生错误的时候调用
server.on("error", function() {
	console.log("listen error");
});
 
server.on("close", function() {
	console.log("server stop listener");
});
/*
server.on("connection", function(client_sock) {
	console.log("client comming 22222");
});
*/
// 编写代码,指示这个server监听到哪个端口上面。
// 127.0.0.1: 6080
// node就会来监听我们的server,等待连接接入
server.listen({
	port: 6081,
	exclusive: true,
});
 
// 停止node对server的监听事件处理,那么node就没有其他的事件要处理,所以就退出了。
// server.unref(); // 取消node,对server的事件的监听;
// server.close(); // 主动的掉这个server.close才会触发这个net.Server的close事件

使用ctrl+~呼出中断输入node server.js可以运行

 

 使用网络调试助手连接

 连接成功

 当服务器接受到信息会调用

client_sock.on("data", function(data) {

    var dividedArray = Array.from(data).map(byte => byte / 256);
    console.log("TCP (Divided Array):", dividedArray);
        // mydata1=data;
            console.log(dividedArray);
        mydata=dividedArray;
    //   clients.forEach(function(sock) {
    //     sock.write(data);
    // });
		// client_sock.end(); // 正常关闭
	});

在接受到数据后,把每个byte除以256得到归一化的数据,并且赋值给全局变量mydata

比如发送31 32 33 34 35 31 32 33 ff 35 31 32 33 34 35 31 32 33 34 35 31 32 33 34 35 31 32 33 34 ff 31 32 33 34 35 31 32 38 37 

因为是以16进制发送,31对应十进制是49,49/256=0.19140625,对应第一个点

 到这里就实现了服务器能够接受到数据并且归一化

4.requirejs导入

参考

4.1在js文件夹下面创建1.js

console.log("成功进入 1.js");

// 加载模块 ,注意不需要写.js的后缀,默认导入文件就是js脚本.
requirejs(['2'], function(val) 
{
    console.log("2.js 加载模块");
});

4.2在js文件夹下面创建2.js

首先打开终端安装highcharts

npm install highcharts --save

// 测试
console.log("成功进入 2.js");
// 导入 node 模块包
require.config(
    {
        packages:
        [{
            name: 'highcharts',
            main: 'highcharts'
        }],
        paths:
        {
            // 这里是 Highcharts 路径
            'highcharts': '../../node_modules/highcharts'
        }
    });
    require(['highcharts'], function (Highcharts) 
    {
        console.log("2.js 加载模块");
        
        testHighcharts(Highcharts)
    });
    
    // 测试 模块包 功能
    function testHighcharts(Highcharts)
    {
        // 测试 图表配置
        const options = 
        {
            chart:{type: 'line',smoothLines:true},
            title:{text: '幅频特性曲线'},
            xAxis:
            {
                categories: Array.from({ length: 41 }, (_, i) => i.toString()),// x 轴分类
                tickAmount: 20,
                gridLineWidth: 1, // y 轴网格线宽度
                gridLineColor: '#e9e9e9', // y 轴网格线颜色
                // startOnTick: true, // 禁用从刻度线开始
                // endOnTick: true, // 禁用到刻度线结束
                // minPadding: 0, // 最小内边距为0
                // maxPadding: 0 // 最大内边距为0
            },
            yAxis:
            {
                title:{text: '归一化曲线'} ,// y 轴标题
                min:0,
                max:1,
                tickAmount: 11, // 设置网格线数量为5
                gridLineWidth: 1, // y 轴网格线宽度
                gridLineColor: '#e9e9e9' // y 轴网格线颜色
            },
            series:
            [
                // {name: '小明',data: [4, 2, 9]}, 
                {name: '幅频特性',data:Array.from({ length: 41 }, (_, i) => i * 0.02) }
            ]
        };
        // 测试 图表初始化函数
        const chart = Highcharts.chart('container', options);
        // 更新数据函数
         function updateData(newData) {
            options.series[0].data = newData; // 更新数据
            chart.update(options); // 更新图表
        }

    // 模拟定时更新数据,每秒更新一次
    setInterval(() => {
                fetch('/api/data')
                .then(response => response.json())
                .then(data => {
                // 在这里处理从服务器返回的数据
                
                updateData(data);
                // drawChart(data); // 假设有一个名为drawChart的函数用于绘制图表,你可以根据实际情况进行调整
                })
                .catch(error => {
                console.error('发生错误:', error);
                });
            // const newData = Array.from({ length: 40 }, (_, i) => i * 0.01); // 获取新的数据
            // updateData(newData); // 调用更新数据函数
            }, 2000);
    }
   

4.3修改1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="../static/js/require.js" defer async="true" data-main="../static/js/1"></script>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="container" style="width: 800px;height:400px;margin: 0 auto;border-style:dashed ; 
    border-width: 5px; "></div>
</body>
</html>

这时候运行就能看到图表了,每隔2秒钟刷新一次

 这段代码在前端中实现每2秒向服务器发送请求

   // 模拟定时更新数据,每秒更新一次
    setInterval(() => {
                fetch('/api/data')
                .then(response => response.json())
                .then(data => {
                // 在这里处理从服务器返回的数据
                
                updateData(data);
                // drawChart(data); // 假设有一个名为drawChart的函数用于绘制图表,你可以根据实际情况进行调整
                })
                .catch(error => {
                console.error('发生错误:', error);
                });
            // const newData = Array.from({ length: 40 }, (_, i) => i * 0.01); // 获取新的数据
            // updateData(newData); // 调用更新数据函数
            }, 2000);
    }

服务器收到请求后将数据发给前端绘制曲线

app.get('/api/data', (req, res) => {
    // 从服务器获取数据
    // const data = getDataFromServer(); // 这里需要根据你的实际情况编写获取数据的逻辑
    // mydata = Array.from({ length: 40 }, (_, i) => i * 0.01) ;
    // console.log("https:",mydata);
    // const data = Array.from({ length: 40 }, (_, i) => i * 0.01) ;
    // 将数据转换为JSON格式并发送回前端
    res.json(mydata);
    // res.mydata;
  });

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于涉及到服务器文件的遍历,需要使用服务器端的代码。以下是使用Node.js实现服务器文件遍历的示例代码: ```javascript const fs = require('fs'); // 定义遍历函数 function traverseFolder(folderPath) { fs.readdir(folderPath, function(err, files) { if (err) { console.error(err); return; } files.forEach(function(file) { const fullPath = folderPath + '/' + file; fs.stat(fullPath, function(err, stats) { if (err) { console.error(err); return; } if (stats.isDirectory()) { // 如果是文件夹,递归进入 traverseFolder(fullPath); } else { // 如果是文件,可以做相应的处理 console.log(fullPath); } }); }); }); } // 调用遍历函数 traverseFolder('/path/to/your/folder'); ``` 上述代码中,`traverseFolder`函数用于遍历指定路径下的所有文件和文件夹。对于每个文件夹,递归进入;对于每个文件,可以做相应的处理,例如打印路径。 此外,还需要在Node.js使用HTTP模块搭建一个简单的Web服务器,以便在浏览器中访问文件列表。以下是示例代码: ```javascript const http = require('http'); const fs = require('fs'); const path = require('path'); // 定义遍历函数 function traverseFolder(folderPath, callback) { fs.readdir(folderPath, function(err, files) { if (err) { callback(err); return; } const results = []; files.forEach(function(file) { const fullPath = folderPath + '/' + file; fs.stat(fullPath, function(err, stats) { if (err) { callback(err); return; } const item = { name: file, path: fullPath, isDirectory: stats.isDirectory() }; if (stats.isDirectory()) { // 如果是文件夹,递归进入 traverseFolder(fullPath, function(err, children) { if (err) { callback(err); return; } item.children = children; results.push(item); if (results.length === files.length) { callback(null, results); } }); } else { // 如果是文件,直接添加到结果数组中 results.push(item); if (results.length === files.length) { callback(null, results); } } }); }); }); } // 创建HTTP服务器 const server = http.createServer(function(req, res) { // 获取当前路径 const currentPath = '.' + req.url; // 如果是文件,直接返回文件内容 if (fs.existsSync(currentPath) && fs.statSync(currentPath).isFile()) { fs.readFile(currentPath, function(err, data) { if (err) { res.writeHead(500); res.end(); return; } res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end(data); }); return; } // 如果是文件夹,返回文件列表 traverseFolder(currentPath, function(err, results) { if (err) { res.writeHead(500); res.end(); return; } // 生成HTML代码,展示文件列表 let html = '<ul>'; results.forEach(function(item) { html += '<li>'; if (item.isDirectory) { html += '<a href="' + item.path + '">' + item.name + '</a>'; if (item.children) { html += '<ul>'; item.children.forEach(function(child) { html += '<li><a href="' + child.path + '">' + child.name + '</a></li>'; }); html += '</ul>'; } } else { html += item.name; } html += '</li>'; }); html += '</ul>'; res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(html); }); }); // 启动服务器 server.listen(8080, function() { console.log('Server is listening on port 8080'); }); ``` 上述代码中,`traverseFolder`函数的作用与之前的示例代码相同,但这里将结果包装为一个对象数组,以便在浏览器中进行展示。同时,返回的结果是一个异步回调函数的参数,而非直接输出到控制台。 在HTTP服务器中,首先判断当前请求的路径是否是一个文件,如果是,则直接返回文件内容。否则,调用`traverseFolder`函数获取文件列表,并生成HTML代码,向浏览器输出。需要注意的是,这里使用了`fs.existsSync`和`fs.statSync`函数判断当前路径是否是一个文件,以避免遍历整个文件夹。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值