使用d3.js,node.js,postgresql显示动态直方图

时间:2015-08-17 15:43:35

标签: javascript node.js postgresql express d3.js

我使用node.js从postgresql数据库中获取数据,并且我在浏览器中以数组形式完美地显示了这些数据。我还使用node.js显示了静态直方图(用d3.js代码制作)。直方图还使用静态数组值。数据库值和静态直方图都在我的浏览器页面上单独显示。现在我想做的是使这个直方图动态化,以便直方图使用数据库值。我不知道如何将数据库值分配给直方图?

我用简单的node.js尝试但不行。

/**
 * Created by Raees Afridi on 8/17/2015.*/

var http = require('http');
var fs = require('fs');
var pg = require('pg');
var conString = "pg://postgres:raees@localhost:5432/tweetdb";

function onRequest(req, res) {

    if(req.method == 'GET' && req.url == '/') {

        res.writeHead(200, {"Context-Type": "text/html"});
        var client = new pg.Client(conString);
        client.connect();
        var query = client.query("SELECT t_follower, t_text FROM columbia ORDER BY t_follower desc limit 4");
        query.on("row", function (row, result) {
            result.addRow(row);
        });
        query.on("end", function (result) {
            var mydata = res.end(JSON.stringify(result.rows, null, "    "));
            console.log(mydata);
            client.end();
        });

        fs.createReadStream("./index.html").pipe(res);

    }





}

http.createServer(onRequest).listen(3000);
console.log("Server is running...")

我使用以下代码使用express框架进行尝试:

<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
    <style>
        .pumpkin {
            fill: yellow;
            stroke: orange;
            stroke-width: 5;
        }
    </style>

</head>
<body>
<% include templates/header.ejs%>
<h3><%= title %> Page</h3>
<% root = JSON.parse( tweetdata ); %>
<ul>
    <% root.forEach(function(item) { %>
    <li><%= item.t_friends %></li>
    <% })%>
</ul>



    <% var dataset = Array(); var i=0; %>
    <% root.forEach(function(item) { %>
    <% dataset[i] = parseInt(item.t_friends); %>
    <% i+=1; }); %>
<% var dataset = dataset %>
<script type="text/javascript">

   // var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
 //11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
</script>


<script type="text/javascript">

    //Width and height
    var w = 500;
    var h = 100;
    var barPadding = 1;
   // var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
       // 11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];

    //var dataset = tweetdata;

    //Create SVG element
    var svg = d3.select("body")
            .append("svg")
            .attr("width", w)
            .attr("height", h);

    svg.selectAll("rect")
            .data(dataset)
            .enter()
            .append("rect")
            .attr("x", function(d, i) {
                //return i * 21;    //Bar width of 20 is already defined and plus 1 for padding
                return i * (w / dataset.length);
            })
            .attr("y", function(d) {
                return h - (d * 4);
            })
            .attr("width", w / dataset.length - barPadding)
        //.attr("height", 100);
            .attr("height", function(d) {
                return d * 4;
            })
            .attr("fill", function(d) {
                return "rgb(0, 0, " + (d * 10) + ")";
            });

    svg.selectAll("text")
            .data(dataset)
            .enter()
            .append("text")
            .text(function(d) {
                return d;
            })
            .attr("text-anchor", "middle")
            .attr("x", function(d, i) {
                return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
            })
            .attr("y", function(d) {
                return h - (d * 4) + 14;
            })
            .attr("font-family", "sans-serif")
            .attr("font-size", "11px")
            .attr("fill", "white");

</script>



</body>
</html>

任何想法?

1 个答案:

答案 0 :(得分:1)

我会创建一个单独的休息服务来检索您的数据,而不是在您的根请求中发送它。

这样你就可以返回一个d3可用于图表的json对象。 (您当前正在返回一个字符串,我认为这是您的图表未呈现的主要原因)。

d3有一个从休息服务获取json的方法,因此您可以使用它来检索数据并在返回数据后呈现图表。

我正在使用您帖子中的node.js示例,但您可能需要查看快速路由来处理您的服务:

if(req.method == 'GET' && req.url == '/getchartdata') {
    var client = new pg.Client(conString);
    client.connect();
    var query = client.query("SELECT t_follower, t_text FROM columbia ORDER BY t_follower desc limit 4");
    query.on("row", function (row, result) {
        result.addRow(row);
    });
    query.on("end", function (result) {
        res.status(200)
        res.json(result.rows);
        client.end();
    });


}

然后在你的剧本中:

 //Width and height
    var w = 500;
    var h = 100;
    var barPadding = 1;
 //Create SVG element
    var svg = d3.select("body")
        .append("svg")
        .attr("width", w)
        .attr("height", h);

 d3.json('/getchartdata', function(error, dataset) {

        svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x", function(d, i) {
            //return i * 21;    
            //Bar width of 20 is already defined and plus 1 for padding
            return i * (w / dataset.length);
        })
        .attr("y", function(d) {
            return h - (d * 4);
        })
        .attr("width", w / dataset.length - barPadding)
      //.attr("height", 100);
        .attr("height", function(d) {
            return d * 4;
        })
        .attr("fill", function(d) {
            return "rgb(0, 0, " + (d * 10) + ")";
        });

        svg.selectAll("text")
        .data(dataset)
        .enter()
        .append("text")
        .text(function(d) {
            return d;
        })
        .attr("text-anchor", "middle")
        .attr("x", function(d, i) {
            return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
        })
        .attr("y", function(d) {
            return h - (d * 4) + 14;
        })
        .attr("font-family", "sans-serif")
        .attr("font-size", "11px")
        .attr("fill", "white");

  });