从0开始搭建Flask-Echarts数据可视化项目


项目结构参考重庆2020年巴渝工匠杯市赛题目、2019年重庆市h3c大数据挑战赛题目

项目代码已托管到github,地址见:https://github.com/ybqdren/BygjRace-DataShowChart








- 一、起步-新建项目

配置环境

1.新建Python项目 命名为01_MyFlaskTest

2.在Teminal中安装pipenv

pip install pipenv

3.创建当前项目空间的虚拟环境

pipenv install

4.激活虚拟环境

pipenv shell

在teminal中执行上述指令,会返现项目路径前出现’(虚拟环境名称)$'类似字段。

这表明Pipenv已经为我们的项目激活了虚拟环境的子shell,此时虚拟环境表示已经激活成功了



安装三方包

1.安装flask

pipenv install flask

2.安装flask-sqlalchemy

pipenv install flask-sqlalchemy

3,安装Jinja2

pipenv install jinja2

4.安装flask-mysqldb(sqlalchemy连接mysql数据库必须)

pipenv install mysqldb

5.安装flask-migrate

pipenv install flask-migrate

6.安装flask-script

pipenv install flask-script

7.安装SQLAlchemy

pipenv install SQLAlchemy


按照目录规范添加目录

如图:
在这里插入图片描述




-二、开始编码

Flask实例对象准备

1.定义flask app实例创建工厂函数

app/_init_.py

def create_app(app_name):
    app = Flask(app_name)
    return app

2.在工厂函数中装配db

app/extensions.py

from flask_sqlalchemy import SQLAlchemy
from flask import Flask

#创建对象
db = SQLAlchemy()

#初始化
def config_extensions(app):
    db.init_app(app)

app/config.py

import os

class Config():
    SQLALCHEMY_DATABASE_URI = 'mysql://root:666666@127.0.0.1:3306/race_flask'
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    SQLALCHEMY_ECHO = True

app/_init_.py

def create_app(app_name):
    app = Flask(app_name)
    app.config.from_object(Config)
    config_extensions(app)  #装配SQLAlchemy对象 db
    return app


蓝图准备

1.创建蓝图实例对象

app/views/main.py

from flask import Blueprint

# 创建蓝图
main_print = Blueprint('main_print',__name__)

2.提供蓝本注册函数

app/veiws/main/_init_.py

from .main import main_print

# 封装
DEFAULT_BLUEPRINT = {
    (main_print,'')
}

#蓝图注册
def config_blueprint(app):
    for blueprint,prefix in DEFAULT_BLUEPRINT:
        app.register_blueprint(blueprint,prefix=prefix)


前端页面准备

1.echarts文件构建下载

https://echarts.apache.org/zh/builder.html

2.前端显示页面准备

app/templates/main/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据可视化展示页面</title>
    <script src="/static/js/echarts.min.js"></script>
</head>
<body>

</body>
</html>

3.蓝图中构建视图函数

app.views.main.py

from flask import render_template

@main_print.route('/index')
def index():
    return render_template('/main/index.html')



- 三、数据与模型类

模型类

app/modles/tbl_video_game_sales.py

from app.extensions import db

class Tbl_Video_Game_Sales(db.Model):
    __tablename__ = 't_video_game_sales'
    Rank = db.Column(db.String(255),primary_key=True)   #销售排名
    Name = db.Column(db.String(255))     #游戏名称
    Platform = db.Column(db.String(255))    #该游戏发布平台
    Year = db.Column(db.Integer)    #发布年份(1980-2016)
    Genre = db.Column(db.String(255))   #游戏类型
    Publisher = db.Column(db.String(255))    #出版公司
    NA_Sales = db.Column(db.DECIMAL(255,2))  #北美区域销量(以百万为单位计数)
    EU_Sales = db.Column(db.DECIMAL(255,2))  #欧美区域销量(以百位为单位计数)
    JP_Sales = db.Column(db.DECIMAL(255,2))  #日本区域销量(以百位为单位计数)
    Other_Sales = db.Column(db.DECIMAL(255,2))   #其他国家销量(以百位为单位计数)
    Global_Sales = db.Column(db.DECIMAL(255,2))   #全球销量(以百位为单位计数)

app/models/_init_.py

from .tbl_video_game_sales import Tbl_Video_Game_Sales


数据迁移

1.创建迁移仓库

创建数据迁移对象

app/extensions.py

from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from flask_migrate import Migrate,MigrateCommand


#创建对象
db = SQLAlchemy()
migrate = Migrate()

#初始化
def config_extensions(app):
    db.init_app(app)
    migrate.init_app(app,db)

manager.py

from app import create_app
from app.views import config_blueprint
from flask_script import Manager
from flask_migrate import MigrateCommand

app = create_app('app')
config_blueprint(app)
manager = Manager(app)
manager.add_command('db',MigrateCommand)#使用 MigrateCommand类使用db命令附加

if __name__ == '__main__':
    manager.run()

Terminal上输入

python manage.py db init

flask-migrate会为我们生成一个迁移文件夹
在这里插入图片描述

2.创建迁移脚本

python manage.py db migrate

使用migrate子命令可以自动生成迁移脚本
在这里插入图片描述



ORM模型映射

此处参考:https://flask-sqlalchemy.palletsprojects.com/en/2.x/contexts/

当前步骤在Python Console中完成

1.导入工厂函数创建Flask实例对象

from app import create_app
app = create_app('app')

2.设置应用上下文(重要!)

app.app_context().push()

如果此处不推送上下文,会报错:No application found. Either work inside a view function or push an application context.

3.导入实例化的SQLAlchemy对象db,并绑定app

from app.extensions import db
db.init_app(app)

此时查看db对象,就会发现已经成功绑定了flask实例对象,并成功读取到配置信息

在这里插入图片描述

4.导入orm模型类

from app.models import Tbl_Video_Game_Sales

5.执行db.create_all()指令

db.create_all()
db.session.commit()

6.测试orm模型映射是否成功

Tbl_Video_Game_Sales.query.all()[:2]

查询结果
在这里插入图片描述




- 四、数据可视化

建立页面模板 ‘base.html’

app/templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block head_title%}{% endblock head_title%}</title>
    <script src="/static/js/echarts.min.js"></script>
    <style>
        #main{
            width: 1000px;
            height: 500px;
            margin-left: auto;
            margin-right: auto;
            margin-top:20px;
        }

        #content-id{
            text-align: center;
            font-size: 30px;
            padding-top: 20px;
        }
    </style>
</head>
    {% block content%}
    {% endblock content%}
</html>

导入模型类

from app.models import Tbl_Video_Game_Sales

开启调试模式

from flask_script import Server
manager.add_command("runserver",Server(use_debugger=True))

1.柱状图

柱形图 -> 同一对象不对维度份额比较

视图函数

@main_print.route('/charts/bar')
def charts_bar():
    game_sale = Tbl_Video_Game_Sales.query.first()
    return  render_template('/main/bar-chart.html',game_sale = game_sale)

页面

{% extends 'base.html'%}

{% block head_title %}
数据可视化展示-柱状图
{% endblock head_title%}

{% block content %}
    <body>
        <div id="content-id">柱状图-bar</div>
        <div id="main"></div>
        <script type="text/javascript">
            var barChart = echarts.init(document.getElementById('main'));

            var option = {
                title: {
                    text: '{{game_sale.Name}}各区域销量',
                    subtext: '单位:百万'
                },
                tooltip:{},
                xAxis: {
                    data: ["北美","欧美","日本","其他国家"]
                },
                yAxis: {
                    type:'value'
                },
                series: [{
                    name: '销量',
                    type: 'bar',
                    data: [{{game_sale.NA_Sales}}, {{game_sale.EU_Sales}}, {{game_sale.jp_Sales}}, {{game_sale.Other_Sales}}]
                }]
            };

            barChart.setOption(option);
        </script>
    </body>
{% endblock content %}

在这里插入图片描述



2.折线图

数据i变化趋势

视图函数

@main_print.route('/charts/line')
def charts_line():
    game = dict()
    for y in range(1999,2011,1):
        count = Tbl_Video_Game_Sales.query.filter(Tbl_Video_Game_Sales.Year == y).count()
        game[y] = count
    return render_template('/main/line-chart.html',game = game)

页面

{% extends 'base.html'%}

{% block head_title%}
数据可视化展示-折线图
{% endblock %}

{% block content %}
    <body>
        <div id="content-id">折线图-line</div>
        <div id="main"></div>
    </body>
    <script>
        var line_chart = echarts.init(document.getElementById('main'));
        var option = {
            title:{
                text:'2000年~2010年发行游戏数量增长趋势',
                subtext:'单位:个'
            },
            tooltip:{},
            xAxis:{
                type:'category',
                data:[{%for g in game%}'{{ g }}',{% endfor %}]
            },
            yAxis:{},
            series:[{
                type:'line',
                data:[{% for g in game%}{{game[g]}},{% endfor %}]
            }]
        };

        line_chart.setOption(option);
    </script>
{% endblock %}

在这里插入图片描述



3.双图表切换(折线/柱)

视图函数

@main_print.route('/charts/changeView')
def change_View():
    game_sale = Tbl_Video_Game_Sales.query.order_by(Tbl_Video_Game_Sales.Global_Sales.desc()).first()
    return render_template('/main/changeView-chart.html',game_sale = game_sale)

页面

{% extends 'base.html' %}

{% block head_title%}
图像切换-折线图/柱状图
{% endblock head_title%}

{% block content %}
    <body>
        <div id="content-id">折线图/柱形图-line/bar</div>
        <div id="main"></div>
    </body>
    <script>

        my_chart = echarts.init(document.getElementById('main'));

        var option = {
            title:{
                text:'一个简单的折/柱切换图',
            },
            tooltip:{
                trigger:'item'
            },
            toolbox:{
                feature:{
                    magicType:{
                        type:['line','bar']
                    }
                }
            },
            xAxis:{
                type:'category',
                data:["北美","欧美","日本","其他国家"]
            },
            yAxis: {},
            series:[{
                type:'line',
                data: [{{game_sale.NA_Sales}}, {{game_sale.EU_Sales}}, {{game_sale.jp_Sales|default('3.5')}}, {{game_sale.Other_Sales}}]
            }]
        };

        my_chart.setOption(option);

    </script>
{% endblock content %}

在这里插入图片描述



4.雷达图

多维度数据展示

视图函数

@main_print.route('/charts/radar')
def charts_radar():
    game = Tbl_Video_Game_Sales.query.filter(Tbl_Video_Game_Sales.Platform == 'Wii').all()[:3]
    return render_template('/main/radar-chart.html',game = game)

页面

{% extends 'base.html'%}

{% block head_title %}
数据可视化展示-雷达图
{% endblock head_title %}

{% block content %}
<body>
    <div id="content-id">雷达图-radar</div>
    <div id="main"></div>

    <script>
        var na_sales = [{% for g in game%}{{ g.NA_Sales }},{% endfor %}];    //北美地区销量
        var eu_sales = [{% for g in game %}{{ g.EU_Sales }},{% endfor %}];    //欧美地区销量
        var jp_sales = [{% for g in game %}{{ g.JP_Sales }},{% endfor %}];      //日本地区销量
        var other_sales = [{% for g in game%}{{ g.Other_Sales }},{% endfor %}];   //其他地区销量

        var radar_chart = echarts.init(document.getElementById('main'));

        var option = {
            title:{
                text:'各区域销量'
            },
            tooltip:{},
            legend:{
                data:[{% for g in game %}'{{ g.Name }}',{% endfor %}],
            },
            radar:{
                indicator:[
                    {name:'北美',max:50},
                    {name:'欧洲',max:50},
                    {name:'日本',max:50},
                    {name:'其他',max:50}
                ]
            },
            series: [{
                type:'radar',
                data:[
                    {% for g in game%}
                    {
                        value:[na_sales[{{ loop.index }}-1],eu_sales[{{ loop.index }}-1],jp_sales[{{ loop.index }}-1],other_sales[{{ loop.index }}-1]],
                        name:'{{ g.Name }}'
                    },
                    {% endfor %}
                ]
            }]
        };

        radar_chart.setOption(option);
    </script>
</body>
{% endblock content %}

在这里插入图片描述



5.饼图

同一对象组成展示

视图函数

@main_print.route('/charts/pie')
def charts_pie():
    game = Tbl_Video_Game_Sales.query.filter(Tbl_Video_Game_Sales.Platform == 'PS3').order_by(Tbl_Video_Game_Sales.Global_Sales.desc()).all()[:10]
    return render_template('/main/pie-chart.html',game = game)

页面

{% extends 'base.html' %}

{% block head_title%}
数据可视化展示-饼图
{% endblock head_title%}

{% block content %}
<body>
    <div id="content-id">饼图-pie</div>
    <div id="main"></div>

    <script>
        var na_sales = [{% for g in game %}{{ g.NA_Sales}},{% endfor %}];
        var eu_sales = [{% for g in game %}{{g.EU_Sales}},{% endfor %}];
        var jp_sales = [{% for g in game %}{{g.JP_Sales}},{% endfor %}];
        var other_sales = [{% for g in game %}{{g.Other_Sales}},{% endfor %}];

        var avg_na =eval( na_sales.join("+"));
        var avg_eu = eval(eu_sales.join("+"));
        var avg_jp = eval(jp_sales.join("+"));
        var avg_other = eval(other_sales.join("+"));

        var pie_chart = echarts.init(document.getElementById('main'));
        var option = {
            title:{
                text:'PS3平台游戏销量区域份额',
                subtext:'摘取销量前十游戏数据'
            },
            tooltip:{
                formatter:'【{b}区域销量】 <br/> {c}百万份({d}%)'
            },
            legend:{
                data:['北欧','欧洲','日本','其他']
            },
            series:[
                {
                    type:'pie',
                    radius:['25%','50%'],
                    data:[
                        {value:avg_na,name:'北欧'},
                        {value:avg_eu,name:'欧洲'},
                        {value:avg_jp,name:'日本'},
                        {value:avg_other,name:'其他'}
                    ]
                }
            ]
        };
        pie_chart.setOption(option);

    </script>
</body>
{% endblock content %}

在这里插入图片描述



6.南丁格尔图(玫瑰图)

比饼图更直观

视图函数

@main_print.route('/charts/rosePie')
def charts_rosePie():
    game = Tbl_Video_Game_Sales.query.filter(Tbl_Video_Game_Sales.Platform == 'PS3').order_by(Tbl_Video_Game_Sales.Global_Sales.desc()).all()[:10]
    return render_template('/main/rosePie-chart.html',game = game)

页面

{% extends 'base.html' %}

{% block head_title%}
数据可视化展示-南丁格尔图
{% endblock head_title%}

{% block content %}
<body>
    <div id="content-id">南丁格尔图-rosePie</div>
    <div id="main"></div>

    <script>
        var na_sales = [{% for g in game %}{{ g.NA_Sales}},{% endfor %}];
        var eu_sales = [{% for g in game %}{{g.EU_Sales}},{% endfor %}];
        var jp_sales = [{% for g in game %}{{g.JP_Sales}},{% endfor %}];
        var other_sales = [{% for g in game %}{{g.Other_Sales}},{% endfor %}];

        var avg_na =eval( na_sales.join("+"));
        var avg_eu = eval(eu_sales.join("+"));
        var avg_jp = eval(jp_sales.join("+"));
        var avg_other = eval(other_sales.join("+"));

        var pie_chart = echarts.init(document.getElementById('main'));
        var option = {
            title:{
                text:'PS3平台游戏销量区域份额',
                subtext:'摘取销量前十游戏数据'
            },
            tooltip:{
                formatter:'【{b}区域销量】 <br/> {c}百万份({d}%)'
            },
            legend:{
                data:['北欧','欧洲','日本','其他']
            },
            series:[
                {
                    type:'pie',
                    radius:['25%','50%'],
                    data:[
                        {value:avg_na,name:'北欧'},
                        {value:avg_eu,name:'欧洲'},
                        {value:avg_jp,name:'日本'},
                        {value:avg_other,name:'其他'}
                    ],
                    roseType:'radius'   //area
                }
            ]
        };
        pie_chart.setOption(option);

    </script>
</body>
{% endblock content %}

在这里插入图片描述




- 项目启动

python manage.py runserver
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 FlaskEcharts 可以很方便地搭建一个数据可视化大屏。以下是一个简单的示例: 1. 安装 FlaskEcharts: ``` pip install flask pip install pyecharts ``` 2. 创建 Flask 应用和路由: ```python from flask import Flask, render_template from pyecharts import options as opts from pyecharts.charts import Bar app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/data') def data(): # 生成数据 x = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] y = [820, 932, 901, 934, 1290, 1330, 1320] # 生成图表 bar = ( Bar() .add_xaxis(x) .add_yaxis('Sales', y) .set_global_opts(title_opts=opts.TitleOpts(title='Weekly Sales')) ) # 渲染图表 return bar.render_embed() ``` 3. 创建 HTML 模板: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Flask Echarts Demo</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.min.js"></script> </head> <body> <div id="chart" style="width: 800px; height: 600px;"></div> <script> var chart = echarts.init(document.getElementById('chart')); chart.showLoading(); fetch('/data').then(function (response) { response.text().then(function (text) { chart.hideLoading(); chart.setOption(JSON.parse(text)); }); }); </script> </body> </html> ``` 4. 启动 Flask 应用: ```python if __name__ == '__main__': app.run() ``` 5. 在浏览器中访问 http://localhost:5000 ,即可看到数据可视化大屏。 注意:以上示例中的数据和图表仅作为演示用途,实际应用中需要根据具体需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值