前期准备:
前期需先实现Flask+plotly输出图表,可以先查看我的上一篇博客
Flask+plotly实现数据可视化(点击查看)
安装VUE:
准备采用 npm(Nodejs下的包管理器)的方式安装vue,所以第一步安装 node , 官网下载安装即可
安装完成之后在 command prompt 运行 node -v , 便可查看到安装的nodejs 的版本,说明安装成功;
npm 是集成在node中的,也可以运行: npm -v 查看安装的npm 版本:
安装cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装vue-cli 脚手架构建工具:
命令行运行npm install -g vue-cli
然后等待安装完成
安装成功之后 运行 vue -V 可查看版本,版本出来的话说明安装成功;
创建VUE项目:
首先通过cd进入项目目录,创建一个vue项目,如下所示
vue init webpack client
? Project name client
? Project description A Vue.js project
? Author hubo <xxxxxxxx@qq.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Airbnb
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
主要写代码的位置:/flask-vue-crud/client/src/,目录结构如下所示:
运行该程序:
npm run dev
访问http://localhost:8080 能看到前端页面
正式开始:
通过axios发送AJAX请求,安装axios,vue-plotly:
cnpm install axios --save
npm install vue-plotly
添加一个新组件
创建client/src/components/Bar.vue:
通过axios从http://192.168.10.163:5000/获取图表的数据,此步中是从已经部署完毕的Flask项目中获取数据,在上一篇文章中有讲解,如果有不懂的可以看看 点击查看,现在的ip换成了ipv4地址,方便内网的同事查看
<template>
<div style="padding: 1em 5em;">
<div style="margin: 10px auto; width: 70%; height: ;" id="mytable">
<div id="app">
<select v-model="aaa" name="fruit">
<option value="">请选择</option>
<option value="http://192.168.10.163:5000/scatter">折线图</option>
<option value="http://192.168.10.163:5000/bar">柱形图</option>
<option value="http://192.168.10.163:5000/line">线形图</option>
<option value="http://192.168.10.163:5000/pie">饼图</option>
<option value="http://192.168.10.163:5000/bubble">泡泡图</option>
<option value="http://192.168.10.163:5000/dot">点图</option>
<option value="http://192.168.10.163:5000/filled">区域图</option>
<option value="http://192.168.10.163:5000/sankey">桑基图</option>
<option value="http://192.168.10.163:5000/table">表图</option>
<option value="http://192.168.10.163:5000/sun">太阳图</option>
</select>
</div>
<!--展现可视化图标部分-->
<Plotly :data="msg" :display-mode-bar="false"></Plotly>
</div>
</div>
</template>
<script>
import axios from 'axios';
import { Plotly } from 'vue-plotly';
export default {
components: {
Plotly,
},
name: 'Bar',
data() {
return {
msg: '',
aaa: '',
scatter: 'http://192.168.10.163:5000/scatter',
bar: 'http://192.168.10.163:5000/bar',
};
},
watch: {
aaa: {
handler: function refresh() {
const path = this.aaa;
axios.get(path)
.then((res) => {
this.msg = res.data;
})
.catch((error) => {
console.error(error);
});
},
},
},
methods: {
getMessage() {
const path = 'http://192.168.10.163:5000/scatter';
axios.get(path)
.then((res) => {
this.msg = res.data;
})
.catch((error) => {
console.error(error);
});
},
},
created() {
this.getMessage();
},
};
</script>
上面Bar.vue中添加了watch监听option的变化,从而从后端获取对应的图形数据。
再添加一个新组件,并把Bar导入,模拟Bar为功能组件,此时新建的Test.vue组件为前端组件。
<template>
<div id="vue_det">
<bar></bar>
<router-view/>
</div>
</template>
<script>
import Bar from '@/components/Bar';
export default{
components: {
Bar,
},
data() {
return {// 这里不要忘记return
// 这里可以定义初始的变量
};
},
created() {
// 当我们的组件加载完成时,需要执行的内容.created是vuejs中的钩子函数之一
this.getData(); // 函数的调用
},
methods: {// 定义函数的地方
getData() {
// console.log(r);
}, // 可以定义多个函数
},
};
</script>
<style>
</style>
更新client/src/router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import HelloWorld from '@/components/HelloWorld';
import Bar from '@/components/Bar';
import Test from '@/components/Test';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
},
{
path: '/bar',
name: 'Bar',
component: Bar,
},
{
path: '/test',
name: 'Test',
component: Test,
},
],
mode: 'history',
});
上面的mode: 'history’是为了让 URL 变成http://localhost:8080/Test的形式。如果,不加该设置,默认的 URL 为http://localhost:8080/#/Test的形式。
访问http://localhost:8080/Test能看到图表
补充:
相对上一篇的Flask中代码有些许变动,整体上是做了模块化,增加了生成图形数据的函数,具体直接上代码
app.py
from flask import Flask
from flask_cors import CORS
from flask import Flask, render_template
from models import create_bar
app = Flask(__name__)
CORS(app)
@app.route('/scatter', methods=['GET'])
def scatter():
data = create_bar.create_scatter()
return data
@app.route('/line')
def line():
data = create_bar.create_line()
return data
@app.route('/bar')
def bar():
data = create_bar.create_bar()
return data
@app.route('/pie')
def pie():
data = create_bar.create_pie()
return data
@app.route('/bubble')
def bubble():
data = create_bar.create_bubble()
return data
@app.route('/dot')
def dot():
data = create_bar.create_dot()
return data
@app.route('/filled')
def filled():
data = create_bar.create_filled()
return data
@app.route('/sankey')
def sankey():
data = create_bar.create_sankey()
return data
@app.route('/table')
def table():
data = create_bar.create_table()
return data
@app.route('/sun')
def sun():
data = create_bar.create_sun()
return data
if __name__ == '__main__':
app.run(
host='0.0.0.0',
port='5000',
debug=True)
create_bar.py
import plotly as py
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
import numpy as np
import json
def create_line():
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color='country')
jsfig=fig.to_json()
return jsfig
def create_scatter():
data1 = {
'x':[1,2,3,4],
'y':[16,5,11,9],
'type':'scatter'
}
data2 = {
'x':[1,2,3,4],
'y':[10,15,13,17],
'type':'scatter'
}
data =[data1,data2]
layout = go.Layout(
title='折线图可视化作图',
)
fig = go.Figure(data=data, layout=layout)
jsfig=fig.to_json()
return jsfig
def create_bar():
animals=['giraffes', 'orangutans', 'monkeys']
fig = go.Figure(
data=[
go.Bar(name='SF Zoo', x=animals, y=[20, 14, 23]),
go.Bar(name='LA Zoo', x=animals, y=[12, 18, 29])
],
layout=go.Layout(
title='柱形图可视化作图',
)
)
# Change the bar mode
fig.update_layout(barmode='group')
jsfig=fig.to_json()
return jsfig
def create_pie():
df = px.data.gapminder().query("year == 2007").query("continent == 'Europe'")
df.loc[df['pop'] < 2.e6, 'country'] = 'Other countries' # Represent only large countries
fig = px.pie(df, values='pop', names='country', title='欧洲各国人口占比')
jsfig=fig.to_json()
return jsfig
def create_bubble():
df = px.data.gapminder()
fig = px.scatter(df.query("year==2007"), x="gdpPercap", y="lifeExp",
size="pop", color="continent",
hover_name="country", log_x=True, size_max=60)
jsfig=fig.to_json()
return jsfig
def create_dot():
schools = ["Brown", "NYU", "Notre Dame", "Cornell", "Tufts", "Yale",
"Dartmouth", "Chicago", "Columbia", "Duke", "Georgetown",
"Princeton", "U.Penn", "Stanford", "MIT", "Harvard"]
n_schools = len(schools)
men_salary = [72, 67, 73, 80, 76, 79, 84, 78, 86, 93, 94, 90, 92, 96, 94, 112]
women_salary = [92, 94, 100, 107, 112, 114, 114, 118, 119, 124, 131, 137, 141, 151, 152, 165]
df = pd.DataFrame(dict(school=schools*2, salary=men_salary + women_salary,
gender=["Men"]*n_schools + ["Women"]*n_schools))
# Use column names of df for the different parameters x, y, color, ...
fig = px.scatter(df, x="salary", y="school", color="gender",
title="性别收入差距",
labels={"salary":"Annual Salary (in thousands)"} # customize axis label
)
jsfig=fig.to_json()
return jsfig
def create_filled():
df = px.data.gapminder()
fig = px.area(df, x="year", y="pop", color="continent",
line_group="country")
jsfig=fig.to_json()
return jsfig
def create_sankey():
fig = go.Figure(go.Sankey(
arrangement = "snap",
node = {
"label": ["A", "B", "C", "D", "E", "F"],
"x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],
"y": [0.7, 0.5, 0.2, 0.4, 0.2, 0.3],
'pad':10}, # 10 Pixels
link = {
"source": [0, 0, 1, 2, 5, 4, 3, 5],
"target": [5, 3, 4, 3, 0, 2, 2, 3],
"value": [1, 2, 1, 1, 1, 1, 1, 2]}))
jsfig=fig.to_json()
return jsfig
def create_table():
fig = go.Figure(data=[go.Table(
header=dict(values=['A Scores', 'B Scores'],
line_color='darkslategray',
fill_color='lightskyblue',
align='left'),
cells=dict(values=[[100, 90, 80, 90], # 1st column
[95, 85, 75, 95]], # 2nd column
line_color='darkslategray',
fill_color='lightcyan',
align='left'))
])
jsfig=fig.to_json()
return jsfig
def create_sun():
data = dict(
character=["Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"],
parent=["", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve" ],
value=[10, 14, 12, 10, 2, 6, 6, 4, 4])
fig =px.sunburst(
data,
names='character',
parents='parent',
values='value',
)
jsfig=fig.to_json()
return jsfig