码迷,mamicode.com
首页 > 数据库 > 详细

使用SQL语句生成 web图表

时间:2015-08-26 20:41:03      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:

简单学了下nodejs web开发框架express,以及一些相关的技术…

关于express的部分主要参考:Node.js开发框架Express4.xNode.js + Express 构建网站简单示例

需要注意的是,express 4.x 构建器独立成了一个模块,如果要使用系统中的express命令,就必须安装独立的generator:

npm install -g express express-generator bower supervisor
express -e bower-express

supervisor 是个好东西,代码变更可以热加载,自动重启:supervisor app.js


(一).首先来看主文件,app.js:

var express = require(‘express‘), ejs = require(‘ejs‘), routes = require(‘./routes/index‘), users = require(‘./routes/users‘), session = require(‘express-session‘), RDBStore = require(‘express-mysql-session‘);
var app = express();
// 定义视图路径及修改ejs模板后缀名
app.set(‘views‘, ‘views‘);
app.engine(‘.html‘, ejs.__express);
app.set(‘view engine‘, ‘html‘);
app.use(require(‘body-parser‘).urlencoded({ extended: false }));
// 定义静态文件路径
app.use(express.static(‘public‘));
app.use(express.static(‘bower_components‘));
// session保存
const options = {
    host : ‘1.1.1.1‘,
    user : ‘test‘,
    port : 5029,
    password : ‘test‘,
    database : ‘test‘
};
app.use(session({
    secret : ‘test‘,
    store : new RDBStore(options),
    cookie : { maxAge: 10000 },
    resave : true,
    saveUninitialized : true
}));
// URL路由
app.get(‘/‘, routes.index).post(‘/‘, routes.index);
// 显示404错误及输出
app.use(function(req, res, next) {
    var err = new Error(‘Not Found‘);
    err.status = 404;
    next(err);
});
// 生产环境异常打印
if (app.get(‘env‘) === ‘development‘)
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render(‘error‘, {
            message: err.message,
            error: err
        });
    });
// 启动及端口
//require(‘http‘).createServer(app).listen(3000);
app.listen(3000, function() {
    console.log(‘Express server listening on 3000‘);
});

由于没装No-SQL数据库,因此就用mysql来缓存session,

进入express生成的项目后使用npm安装即可:npm install express-mysql-session

用法很简单,启动项目后会在目标库自动新建一张innodb表,可以将其改为memory引擎:

ALTER TABLE sessions MODIFY data VARCHAR(5000),ENGINE=MEMORY;

当然,使用mongos或者rethinkdb会更方便,问题是node模块太多了有点眼花缭乱不知道用哪个好(bug少)……譬如:

npm install express-session-rethinkdb connect-rethinkdb session-rethinkdb


(二).好吧,接下来看“action”,routes/index.js:

var router = require(‘express‘).Router(), mysql = require(‘mysql‘);

const options = [{ host : ‘1.1.1.1‘, user : ‘test‘, port : 5029, password : ‘test‘, database : ‘test‘, dateStrings : true }, {
{ host : ‘1.1.1.2‘, user : ‘test‘, port : 3306, password : ‘test‘, database : ‘test‘, dateStrings : true }, {
{ host : ‘1.1.1.3‘, user : ‘test‘, port : 3307, password : ‘test‘, database : ‘test‘, dateStrings : true//, multipleStatements : true
}];

module.exports.index = function(req, res) {
    var connection, sql;
    if (req.method == ‘POST‘ && req.body && req.body.host && /^[1-3]$/.test(req.body.host) && req.body.title && req.body.sql) {
        //var pool = mysql.createPool(options[2]);
        connection = mysql.createConnection(options[req.body.host]);
        sql = req.body.sql;
    } else {
        res.render(‘index‘, {
            ‘params‘ : { title : ‘‘, sql : ‘‘, host : ‘‘}, ‘x‘ : ‘[]‘, ‘y‘ : ‘[]‘
        });
        return;
    }
    connection.query(sql, function(err, rows, fields) {
        if (err) throw err;
        var x = [], y = [];
        for (var i in rows) {
            //if (rows[i].x instanceof Date) x[i] = require(‘moment‘)(rows[i].x).format(‘YYYY-MM-DD‘);
            x[i] = rows[i].x;
            y[i] = rows[i].y;
        }
        res.json({ ‘x‘ : x, ‘y‘ : y });
    });
    connection.end();
};

代码很简单,GET请求直接返回页面(当然也可以处理queryString),POST请求返回JSON数据。

一开始不知道node-mysql有个 dateStrings的参数,所以用 moment.js来转换日期格式,也很方便。

在开发页面前先使用 bower下载好所需的jQuery、BootstrapACEECharts等库:

bower install ace echarts bootstrap jquery


(三).最后来上展示页面,views/index.html:

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <title><%-params.title%></title>
    <link rel="stylesheet" href="bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
    <div id="editor" style="height:60px;font-size:16px"><%-params.sql%></div>
    <form style="width:60%;height:90px;padding:10px 40px">
        <div class="form-group col-xs-4" style="padding-left:0px">
            <select class="form-control" name="host">
                <option value="">Select Host</option>
                <option value="0">1.1.1.1:5029</option>
                <option value="1">1.1.1.2:3306</option>
                <option value="2">1.1.1.3:3306</option>
            </select>
        </div>
        <div class="form-group col-xs-4" style="padding-left:0px">
            <input type="text" name="title" class="form-control" placeholder="title" value="<%-params.title%>" />
        </div>
        <button type="button" onclick="query()" class="btn btn-primary">Query</button>
    </form>
    <hr />
    <div id="main" style="height:400px"></div>
    <script src="echarts/build/dist/echarts.js"></script>
    <script type="text/javascript" src="jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="bootstrap/dist/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="javascripts/ace/src-min-noconflict/ace.js"></script>
    <script type="text/javascript">
// js在下面  ↓↓↓↓↓
    </script>
</body>

以上的JS代码如下:

$(‘select‘).val(<%-params.host%>);
var editor = ace.edit(‘editor‘), myChart, options = {
    tooltip: { show: true },
    legend: { data : [‘<%-params.title%>‘] },
    xAxis : [{ type : ‘category‘, data : <%-x%> }],
    yAxis : [{ type : ‘value‘ }],
    series : [{ ‘name‘ : ‘<%-params.title%>‘, ‘type‘ : ‘bar‘, ‘data‘ : <%-y%> }]
};
editor.setTheme(‘ace/theme/sql‘);
editor.getSession().setUseWrapMode(true);
editor.getSession().setMode(‘ace/mode/sql‘);
// 路径配置
require.config({ paths: { echarts: ‘echarts/build/dist‘ } });
// 使用
require(
    [ ‘echarts‘, ‘echarts/chart/bar‘ ],
    function (ec) {
        myChart = ec.init($(‘#main‘).get(0));
        myChart.setOption(options);
    }
);
 
function query() {
    myChart.showLoading();
    $.ajax({
        url : window.location.pathname,
        cache : false,
        type : ‘POST‘,
        dataType : ‘json‘,
        data : $(‘form‘).serialize() + ‘&sql=‘ + editor.getValue(),
        success : function(obj) {
            options.legend.data[0] = $(‘:text‘).val();
            options.xAxis[0].data = obj.x;
            options.series[0].data = obj.y;
            myChart.clear();
            myChart.hideLoading();
            myChart.setOption(options);
        }
    });
}

注意:

  • echarts的 setOption 方法是更新操作,因此要先clear图表后重新绘图;
  • ACE是一个源码编辑器,同大名鼎鼎的CodeMirror类似,API也是大同小异;
  • 如果bower 下载的ACE没有编译,前往ace-builds页面下载。


至此,一个简单的web应用就诞生了,就像 ChartSQL做的那样,可以再完善ajax异常处理、node-mysql的连接池等。

好久没碰过前端相关的技术,写起来各种生疏,代码拙劣、欢迎指教。最后来一张效果图:

技术分享

使用SQL语句生成 web图表

标签:

原文地址:http://my.oschina.net/cwalet/blog/497448

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!