微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – 使用Express创建数据可视化并从PostgreSQL数据库获取数据

我构建了一个Node.js应用程序,它可以从Internet上删除一些信息并将这些信息保存在postgresql数据库中.
现在我想使用D3.js创建一些可视化.
通常我使用.csv文件创建可视化,但现在我想从我的数据库获取数据.

我想使用Express.js.
这是我的代码,它可以工作,但它从.csv文件获取数据,而不是从db.

app.js:

const express = require('express');
var app = express();

const start = async function() {
    console.log('\n(1) Connect to db');
    await postgresqllib.connect();

    console.log('\n(02) Create tables if they do not exist');
    await postgresqllib.createTables();

    console.log('\n(03) Check if table \'example\' is updated or not');
    if(!await utilFunc.isTableupdated('example',6308)) {
        console.log('\n  (04) Download data for coverages');
        await downloader.download();

        console.log('\n  (05) Elaborate data for example before to save on DB');
        await elaborate.elaborate();

        console.log('\n  (06) Saving data on db');
        await saveOnDb.save();
    }   

    console.log('\n(10) D3js visualizations');
    app.set('port',process.env.PORT || 300)
    var server = app.listen(app.get('port'),function() {
        console.log('Listening on PORT: ' + app.get('port'));
    });
    app.use('/',express.static('public/donut')) 

    // I can't disconnect from db if I have to show visualizations,am I right?
    console.log('\n(11) disconnect');
    await postgresqllib.disconnect();
}

start()
.then(function(res) {
    console.log('Done');
})
.catch(function(err) {
    console.log(err);
});

index.html的:

<!DOCTYPE html>
    <html lang="en">
    <head>
       <Meta charset="utf-8">
       <title>Donut</title>
       <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
       <link rel="stylesheet" type="text/css" href="./donut.css" media="screen"/>
    </head>
    <body>
       <script src="./donut.js"></script>
    </body>
</html>

donut.js:

var width = 960,height = 500,radius = Math.min(width,height) / 2;

var color = d3.scale.ordinal()
    .range(["#98abc5","#8a89a6","#7b6888","#6b486b","#a05d56","#d0743c","#ff8c00"]);

var arc = d3.svg.arc()
    .outerRadius(radius - 10)
    .innerRadius(radius - 70);

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.population; });

var svg = d3.select("body").append("svg")
    .attr("width",width)
    .attr("height",height)
  .append("g")
    .attr("transform","translate(" + width / 2 + "," + height / 2 + ")");

d3.csv("./data.csv",type,function(error,data) {
  if (error) throw error;

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class","arc");

  g.append("path")
      .attr("d",arc)
      .style("fill",function(d) { return color(d.data.age); });

  g.append("text")
      .attr("transform",function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy",".35em")
      .text(function(d) { return d.data.age; });
});

function type(d) {
  d.population = +d.population;
  return d;
}

data.csv:

age,population
<5,2704659
5-13,4499890
14-17,2159981
18-24,3853788
25-44,14106543
45-64,8819342
≥65,612463

我也尝试:

const start = async function() {
    //...

    function onRequest(req,res) {
        if(req.method == 'GET' && req.url == '/') {
            var client = new pg.Client(conString);
            client.connect();
            var query = client.query('SELECT * FROM example;');
            query.on('row',function(row,result) {
                result.addRow(row);
            });
            query.on('end',function(result) {
                res.status(200)
                res.json(result.rows);
                client.end();
            });
        }
    }
}

和:

d3.csv("/",data) {
  if(error) { 
    throw error;
  }
  console.log('data:',data);
  ...
}

但它不起作用.

我不会使用.csv文件来存储我的数据,但我想使用db.
我怎样才能做到这一点?

解决方法

我的解决方案要求您安装另外两个模块:

npm install -save express-handlebars& npm install -save pg-promise

之后在app.js中你可以连接到你的postgresql服务器并通过把手助手解析数据,这里是所有的代码.

app.js

const express = require('express');
const exphbs  = require('express-handlebars');
const pgp     = require('pg-promise')(/*options*/);

var app = express();

dbLoad();

function dbLoad() {

  var connect = {
    host: 'localhost',port: 5432,database: 'postgres',user: 'postgres',password: 'YourPassword'
  };

  var db = pgp(connect); 

  db.query({
    text: 'SELECT * FROM table1',values: [],rowMode: 'array'
  })
  .then(data => {
    var arr = [];
    data.forEach(function(d) {
      var i = 0
      arr.push({
        age: d[i],population: d[i + 1]
      })
      i++
    })

    pageLoad(arr); // Function call to load the page

  })
  .catch(reason => {
    console.log(reason)
  });

}

function pageLoad(data) {

  var hbs = exphbs.create({
    helpers: {
      sqlData: function () { return JSON.stringify(data); }
    }
  });

  app.engine('handlebars',hbs.engine);
  app.set('view engine','handlebars');

  app.get('/',function (req,res,next) {
    res.render('home',{

      showTitle: true,});
  });

  app.listen(3000);

}

这假设您的服务器上的数据名为table1,其数据结构与csv完全相同.

然后你应该在与app.js相同的文件夹中创建一个名为views的文件夹,并创建一个名为home.handlebars的文件(这是index.html的替代品)

在此文件中,您将要调用此数据{{sqlData}}并对其进行解析.

home.handlebars

<!DOCTYPE html>
<html>
<head>
<Meta charset="utf-8">
<script src="//d3js.org/d3.v3.min.js"></script>
<title></title>
</head>
<body>

<div id="chart"></div>

</body>

<script>

var init = JSON.parse("{{sqlData}}".replace(/&quot;/g,'"').replace(/&lt;/,''))

chart(init);

function chart(data) {

  var width = 960,height) / 2;

  var color = d3.scale.ordinal()
      .range(["#98abc5","#ff8c00"]);

  var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(radius - 70);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.population; });

  var svg = d3.select("#chart").append("svg")
      .attr("width",width)
      .attr("height",height)
    .append("g")
      .attr("transform"," + height / 2 + ")");

    var g = svg.selectAll(".arc")
        .data(pie(data))
      .enter().append("g")
        .attr("class","arc");

    g.append("path")
        .attr("d",arc)
        .style("fill",function(d) { return color(d.data.age); });

    g.append("text")
        .attr("transform",function(d) { return "translate(" + arc.centroid(d) + ")"; })
        .attr("dy",".35em")
        .text(function(d) { return d.data.age; });

}

</script>
</html>

这应该是它.

注意我不是node.js的专家,如果你担心这个问题可能会有一些严重的安全漏洞,我建议通过express.js api并通过正确的方式来获取json对象直接来自app.js而没有我在此解决方案中所做的所有hacky字符串替换.

编辑:

将字符串替换减少为单行代码

var init = JSON.parse("{{sqlData}}".replace(/&quot;/g,''))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐