行业职位分析项目手册第一套-可视化

任务四:数据可视化

4.1 新建 Flask

项目命名为 ViewData,项目中新建文件夹 app/models 存放数据库映射类,app/static/js存放 js 的外部工具包,app/templates/main 存放 html 前端页面,app/templates/errors存放 404 之后的 html 前端页面,app/views 存放 SQLAlchemy 的语法的数据库访问类。
在这里插入图片描述

4.2 新建 app/init.py

新建 flask 的初始化类,自定义函数 def create_app(config_name)封装一个方法,专门用于创建 Flask 实例;自定义函数 def config_errorhandler(app)编写访问失败之后的404 页面的跳转设置。

from flask import Flask, render_template
from app.config import config
from app.extensions import config_extensions
from app.views import config_blueprint
# 封装一个方法,专门用于创建 Flask 实例
def create_app(config_name): # development
# 创建应用实例
app = Flask(__name__)
# 初始化配置
app.config.from_object(config.get(config_name) or config['default'])
# 调用初始化函数
config[config_name].init_app(app)
# 配置扩展
config_extensions(app)
# 配置蓝本
config_blueprint(app)
# 错误页面定制
config_errorhandler(app)
# 返回应用实例
return app
def config_errorhandler(app):
# 如果在蓝本定制,只针对本蓝本的错误有效,
# 可以使用 app_errorhandler 定制全局有效的错误显示
@app.errorhandler(404)
def page_not_found(e):
return render_template('errors/404.html')

4.3 新建 app/config.py

新建 flask 连接数据库的配置类,将 flask 框架连接数据库的配置编写成函数,包括数据库的 ip、端口、用户名、密码等。

import os
base_dir = os.path.abspath(os.path.dirname(__file__))
# 通用配置
class Config:
# 秘钥
SECRET_KEY = os.environ.get('SECRET_KEY') or '123456' # 数据库
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_TRACK_MODIFICATIONS = False
# 额外的初始化操作,即使什么内容都没有写,也是有意义的
@staticmethod
def init_app(app):
pass
# 开发环境 语法:mysql+pymysql://用户名:密码@ip:端口/数据库名
class DevelopmentConfig(Config):
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/visiondata' # 测试环境
class TestingConfig(Config):
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/visiondata' # 生产环境
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/visiondata' # 配置字典
config = {
'development': DevelopmentConfig, 'testing': TestingConfig, 'production': ProductionConfig,
'default': DevelopmentConfig
}

4.4 新建 app/ extensions.py

导入 flask 相关模块,创建 SQLAlchemy 对象并初始化 Bootstrap。自定义函数 defconfig_extensions(app)完成 SQLAlchemy 和 Bootstrap 的初始化。

# 导入类库
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_moment import Moment
# 创建对象
bootstrap = Bootstrap()
db = SQLAlchemy()
moment = Moment()
migrate = Migrate(db=db)
# 初始化
def config_extensions(app):
bootstrap.init_app(app)
db.init_app(app)
moment.init_app(app)
migrate.init_app(app)

4.5 新建 app/models/表名.py

编写 flask 的数据库表的映射类,每个表格对应一个文件,映射类命名与表名一致。

表 hot_work

from app.extensions import db
class HotWork(db.Model): __tablename__ = 'hot_work'
id = db.Column(db.Integer, primary_key=True)
job_name = db.Column(db.String(255))
job_number = db.Column(db.Integer)

表 bigdata_work

from app.extensions import db
class BigDataWork(db.Model): __tablename__ = 'bigdata_work'
id = db.Column(db.Integer, primary_key=True)
job_name = db.Column(db.String(255))
company_name = db.Column(db.String(255))
city = db.Column(db.String(255))
job_require = db.Column(db.Text)
recruit_number = db.Column(db.String(255))
money = db.Column(db.String(255))
skill_require = db.Column(db.String(255))
release_date = db.Column(db.String(255))
sex = db.Column(db.String(255))
company_detail = db.Column(db.String(255))
education = db.Column(db.String(255))

表 avg_money_city

from app.extensions import db
class AvgMoneyCity(db.Model): __tablename__ = 'avg_money_city'
id = db.Column(db.Integer, primary_key=True)
city = db.Column(db.String(255))
avg_money = db.Column(db.String(255))

表 avg_money_bigdata

from app.extensions import db
class AvgMoneyBigData(db.Model): __tablename__ = 'avg_money_bigdata'
id = db.Column(db.Integer, primary_key=True)
city = db.Column(db.String(255))
avg_money = db.Column(db.String(255))

4.6 新建 app/models/init.py

编写 flask 的访问数据库的初始化文件,导入数据库映射表类。

from app.extensions import db
from .hot_work import HotWork
from .bigdata_work import BigDataWork
from .avg_money_city import AvgMoneyCity
from .avg_money_bigdata import AvgMoneyBigData

4.7 新建 app/static/js

将 html 前段需要用到的 js 工具包存放在 js 文件夹下。

4.8 新建 ViewData/mamage.py

新建 flask 启动类,创建 flask 实例和数据库迁移命令,以及程序的入口。

import os
from app import create_app
from flask_script import Manager, Server
from flask_migrate import MigrateCommand
# 获取配置
config_name = os.environ.get('FLASK_CONFIG') or 'default' # 创建 Flask 实例
app = create_app(config_name)
# 创建命令行启动控制对象
manager = Manager(app)
manager.add_command("runserver", Server(use_debugger=True))
# 添加数据库迁移命令
manager.add_command('db', MigrateCommand)
# 启动项目
if __name__ == '__main__':
manager.run()

4.9 新建 app/views/init.py

新建 flask 的蓝本配置初始化类,进行蓝本的配置,自定义函数 def config_blueprint(app)以及封装函数完成蓝本的注册。

from .main import main
# 蓝本配置
DEFAULT_BLUEPRINT = (
# 蓝本,前缀
(main, ''), )
# 封装函数,完成蓝本注册
def config_blueprint(app):
for blueprint, prefix in DEFAULT_BLUEPRINT:
app.register_blueprint(blueprint, url_prefix=prefix)

4.10 新建 app/views 的 main.py

(1)根据数据库表格 hotwork,分析并统计招聘数量最多的前十名热门职位,分别使用柱状图表达
数据源:数据库 visiondata 中 hot_work 表
在 app/views 下的 main.py 添加函数 def get_hot_work() ,使SQLAlchemy 语法编写 sql 的查询语句,查询统计招聘数据前十的热门职位

# 统计招聘数量最多的前十热门职位 获取结果:
def get_hot_work(): # 编写查询语句 返回前 10 条
# sql: select * from hot_work group by job_name limit 10
ghw_rs = HotWork.query.order_by(desc('job_number')).limit(10)
print(ghw_rs)
return ghw_rs

(2)请根据指定表中的数据,统计出全国某些城市指定招聘岗位平均工资,通过南丁格尔玫瑰图进行呈现。
数据源:数据库 visiondata 中 avg_money_city 和 avg_money_bigdata
在 app/views 下 的 main.py 添 加 函 数 def get_avg_money_city() 和 def
get_avg_money_BigData(),使用 SQLAlchemy 语法编写 sql 的查询语句,查询两个表中的城市平均工资数据。

# 所有城市招聘数据的平均工资 获取结果
def get_avg_money_city():
# sql: select * from avg_money_city
gamc_rs = AvgMoneyCity.query.all()
print('所有城市招聘数据的平均工资 获取结果成功')
return gamc_rs
# “大数据”相关职位所有城市招聘数据的平均工资 获取结果
def get_avg_money_BigData():
# sql: select * from avg_money_big_data
gamb_rs = AvgMoneyBigData.query.all()
print('“大数据”相关职位所有城市招聘数据的平均工资 获取结果成功')
return gamb_rs

(3) 分析并统计招聘数量"大数据"相关职位招聘数量,分别使用柱状图表达,同时在网页后台输出相关数据打印语句。
数据源:数据库 visiondata 中 bigdata_work
在 app/views 下的 main.py 添加函数 def get_big_data_work(),使用 SQLAlchemy语法编写 sql 的查询语句,对相同职位进行数量汇总。

# 对相同职位进行数量汇总,"大数据"相关职位招聘数量比较
def get_big_data_work():
# sql: select job_name,count(*) from bigdata_work where job_name like '%大数据%' GROUP BY
job_name
gbdw_rs = db.session.query(BigDataWork.job_name, func.count('*').label('job_count'))\
.group_by(BigDataWork.job_name).order_by(desc('job_count')).all()
print('"大数据"相关职位招聘数量:' + str(gbdw_rs))
return gbdw_rs

app/views 下的 main.py 完整代码,如下所示。:

import json
from flask import Blueprint, render_template, jsonify
from app.models import HotWork, BigDataWork, AvgMoneyCity, AvgMoneyBigData
from app.extensions import db
from sqlalchemy import * main = Blueprint('main', __name__) # 实例化路由
@main.route('/')
def index():
return render_template('/main/echarts.html') # 当 url 访问 / 直接跳转到主页
@main.route('/index/') # url 访问 /index/ 跳转主页 调用 display 方法 将查询结果通过
render_template()传入 html 页面
def display():
rs_ghw = get_hot_work()
rs_gbdw = get_big_data_work()
rs_gamc = get_avg_money_city()
rs_gamb = get_avg_money_BigData()
return render_template('/main/echarts.html', rs_ghw=rs_ghw, rs_gbdw=rs_gbdw, rs_gamc=rs_gamc, rs_gamb=rs_gamb)
# 统计招聘数量最多的前十热门职位 获取结果:
def get_hot_work(): # 编写查询语句 返回前 10 条
# sql: select * from hot_work group by job_name limit 10
ghw_rs = HotWork.query.order_by(desc('job_number')).limit(10)
print(ghw_rs)
return ghw_rs
# 所有城市招聘数据的平均工资 获取结果
def get_avg_money_city():
# sql: select * from avg_money_city
gamc_rs = AvgMoneyCity.query.all()
print('所有城市招聘数据的平均工资 获取结果成功')
return gamc_rs
# “大数据”相关职位所有城市招聘数据的平均工资 获取结果
def get_avg_money_BigData():
# sql: select * from avg_money_big_data
gamb_rs = AvgMoneyBigData.query.all()
print('“大数据”相关职位所有城市招聘数据的平均工资 获取结果成功')
return gamb_rs
# 对相同职位进行数量汇总,"大数据"相关职位招聘数量比较
def get_big_data_work():
# sql: select job_name,count(*) from bigdata_work where job_name like '%大数据%' GROUP BY
job_name
gbdw_rs = db.session.query(BigDataWork.job_name, func.count('*').label('job_count'))\
.group_by(BigDataWork.job_name).order_by(desc('job_count')).all()
print('"大数据"相关职位招聘数量:' + str(gbdw_rs))
return gbdw_rs

4.11 新建 app/templates/errors/404.html

编写 url 访问失败之后的提示页面。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
404
</body>
</html>

4.12 新建 app/templates/main/echarts.html

编写 js 获取到 flask 传过来的数据,通过 echarts 组件进行结果的展示(包括 css 样式)。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>招聘信息统计</title>
<script type="text/javascript" src="/static/js/echarts.js"></script>
<script type="text/javascript" src="/static/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/js2wordcloud.js"></script>
</head>
<style>
	html , body , .content {
		width:100%;
		height:100%;
		padding: 0;
		margin: 0;
		box-sizing: border-box;
		background-color: #ccc;
	}
	.content {
		padding: 40px;
	}
	.header {
		height: 10%;
		width: 100%;
		font-size: 24px;
		font-weight: 700;
		line-height: 60px;
		text-align: center;
	}
	.body {
		height: 100%;
		width: 100%;
		text-align: center;
	}
	.chartBox {
		width: 100%;
		height: 60%;
		margin-bottom:40px;
	}
</style>
<body>
	<div class="content">
		<div class="header"></div>
		<div class="body">
			<div class="chartBox" id="hotWork"></div>
			<div class="chartBox" id="bigDataWork"></div>
			<div class="chartBox" id="pieAvgMoneyCity"></div>
		</div>
	</div>
</body>
<script>
	//折线图 招聘数量最多的前十热门职位
	var hotWork = echarts.init(document.getElementById('hotWork')); //获取 div 的 id 实例化 echarts 组件
	var data_name = [{% for r in rs_ghw %} "{{r.job_name}}", {% endfor %}] //将职位名job_name 存放在一个数组中作为 x 轴数据
	var data_y = [{% for r in rs_ghw %}"{{r.job_number}}",{% endfor %}] //将职位数量job_number 存放在一个数组中作为 y 轴数据
	console.log('十大热门职位:' + data_name);
	console.log('数据分别为:' + data_y);
	console.log('最大值: ' + Math.max.apply(null, data_y) + ', 最小值:' + Math.min.apply(null, data_y));
	workOption = {
		title: {
			text: '职位分析', //主标题
			subtext: ' ---10 大热门职位分析', //副标题
			x: '45%' //设置标题位置
		},
		xAxis: {
			type: 'category',
			name: '岗位名称',
			data: data_name,
			axisLabel : {
				interval: 0, 
				rotate: "25" //x 轴字体的旋转度
			}
		},
		yAxis: {
			name: '招聘数量',
			type: 'value' 
		},
		series: [
			{
				data: data_y, 
				type: 'line', //设置图形为折线图
				label: {
					normal: {
						show: true, 
						position: 'top' //折线图顶部显示对应的 x 轴数值
					}
				}
			}
		]
	};
	hotWork.setOption(workOption); //设置 echarts 的 option 参数 加载并显示图形
	//南丁格尔玫瑰图
	var pieAvgMoneyCity = echarts.init(document.getElementById('pieAvgMoneyCity'));
	var city = [{% for r in rs_gamc %}"{{r.city}}",{% endfor %}]
	var avg_money_pie_city = [{% for r in rs_gamc %}{value:"{{r.avg_money}}", name:"{{r.city}}"},{% endfor %}]
	var avg_money_pie_bigdata = [{% for r in rs_gamb %}{value:"{{r.avg_money}}", name:"{{r.city}}"},{% endfor %}]
	var avg_money_city = [{% for r in rs_gamc %} "{{r.avg_money}}", {% endfor %}]
	var avg_money_big_data = [{% for r in rs_gamb %}"{{r.avg_money}}",{% endfor %}]
	var dataInt_city = [];
	var dataInt_big_data = [];
	
	dataInt_city.forEach(function(data){
		avg_money_city.push(+parseInt(data)); ///遍历数组 将每个元素变成整型
	});
	dataInt_big_data.forEach(function(data){
		avg_money_big_data.push(+parseInt(data)); ///遍历数组 将每个元素变成整型
	});
	console.log('所有城市平均薪资:' + city);
	console.log('数据分别为:' + avg_money_city);
	console.log("所有城市最大平均薪资为" + Math.max.apply(null, avg_money_city));
	console.log("“大数据”相关职位城市招聘数据的平均工资" + city);
	console.log('数据分别为:' + avg_money_big_data);
	console.log("“大数据”相关职位最大平均薪资为" + Math.max.apply(null, avg_money_big_data));
	
	pieAvgMoneyCityOption = {
		title : {
			text: '所有城市招聘数据的平均工资 vs “大数据”相关职位所有城市招聘数据的平均工资', 
			subtext: '南丁格尔玫瑰图', x:'center' 
		},
		tooltip : {
			trigger: 'item', 
			formatter: "{b}:{c}({d}%)" //当鼠标移动到图形 显示数据(格式): 佛山(1111) 10%
		},
		legend: {
			x : 'center',
			y : 'bottom',
			data:city
		},
		color:[
			'#C1232B','#B5C334','#FCCE10','#E87C25','#27727B', '#668ffe','#00ca54','#00dbfa','#f3006a','#60C0DD', '#d714b7','#84433c','#f490f3','#000000','#26C0C0'
		],
		series : [
			{
				type:'pie', 
				radius : [20, 110], //图像的大小
				center : ['25%', '50%'], //图形的位置
				roseType : 'radius', //南丁格尔玫瑰图的参数
				data:avg_money_pie_city
			},
			{
				type:'pie', 
				radius : [30, 110], 
				center : ['75%', '50%'], 
				roseType : 'area', 
				data:avg_money_pie_bigdata
			}
		]
	};
	pieAvgMoneyCity.setOption(pieAvgMoneyCityOption);
	//柱状图 "大数据"相关职位招聘数量
	var bigDataWork = echarts.init(document.getElementById('bigDataWork'));
	var job_name = [{% for r in rs_gbdw %} "{{r.job_name}}", {% endfor %}]
	var quantity = [{% for r in rs_gbdw %}"{{r.job_count}}",{% endfor %}] // 获取元组中的第二个元素('AI 大数据工程师', 1095)
	console.log('招聘职位: ' + job_name);
	console.log('对应职位招聘数量: ' + quantity);
	console.log('岗位需求量最大: ' + Math.max.apply(null, quantity) + ', 岗位需求量最少:'+ Math.min.apply(null, quantity));
	
	bigdataworkOption = {
		title: {
			text: '大数据相关职位招聘数量', 
			subtext: ' ----职位招聘对比', 
			x: '45%', //modified 0523
			textStyle:{
				//文字颜色
				color:'#f30008', //字体风格,'normal','italic','oblique' fontStyle:'oblique', //字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400... fontWeight:'bold', //字体系列
				fontFamily:'FangSong' //fontFamily: 'KaiTi' //字体大小
				//fontSize:18
			}
		//modified end
		},
		xAxis: {
			type: 'category', 
			name: '职位名称', 
			data: job_name, 
			axisLabel : {
				interval: 0, 
				rotate: "15" //x 轴字体的旋转度
			}
		},
		yAxis: {
			type: 'value', 
			name: '招聘数量' 
		},
		series: [
			{
				data: quantity, 
				type: 'bar', 
				label: {
					normal: {
						show: true, 
						position: 'top' 
					}
				},//modified0523
				itemStyle: {
					normal: {
						color: 'black'
					}
				}
				//modified end
			}
		]
	};
	bigDataWork.setOption(bigdataworkOption);
</script>
</html>

4.13 运行 Flask 程序查看结果

(1)分析并统计招聘数量最多的前十名热门职位,分别使用折线图表达
在这里插入图片描述
(2)分析并统计招聘数量"大数据"相关职位招聘数量,分别使用柱状图表达。
在这里插入图片描述
(3)统计出全国某些城市指定招聘岗位平均工资,通过南丁格尔玫瑰图进行呈现。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值