feat(数据可视化技术): 添加网店运营大屏前端和后端基础结构
- 新建前端项目配置文件和样式文件 - 创建后端 Flask 应用和数据库连接管理器 - 定义多个 API 路由以获取销售数据
28
数据可视化技术/网店运营大屏(Flask框架)/frontend/.project
Executable file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>网店运营大屏</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.aptana.ide.core.unifiedBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.aptana.projects.webnature</nature>
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1596432197735</id>
|
||||
<name></name>
|
||||
<type>26</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-node_modules</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
||||
152
数据可视化技术/网店运营大屏(Flask框架)/frontend/css/app.css
Executable file
@@ -0,0 +1,152 @@
|
||||
@charset "utf-8";
|
||||
|
||||
/********** Global **********/
|
||||
/*
|
||||
*常用背景色: #0f1c30 #0b0f34 (6,64,102) (29,45,57) (7,33,58) (8,13,28) (15,43,36)
|
||||
*/
|
||||
html, body {
|
||||
width:100%;
|
||||
height:100%;
|
||||
min-height:635px;
|
||||
font-family:"microsoft yahei", arial, sans-serif;
|
||||
background-color:#152a59;
|
||||
background-repeat:no-repeat;
|
||||
background-position:center;
|
||||
background-size:100% 100%;
|
||||
overflow-x:hidden;
|
||||
overflow-y:auto;
|
||||
}
|
||||
body.bg06 {background-image:url("../img/bg06.png");}
|
||||
.header {
|
||||
margin:0 auto;
|
||||
width:100%;
|
||||
height:55px;
|
||||
max-width:1920px;
|
||||
background:url("../img/header-left.png") left center no-repeat, url("../img/header-right.png") right center no-repeat;
|
||||
background-size:43% 100%, 43% 100%;
|
||||
overflow:hidden;
|
||||
}
|
||||
.header h3 {
|
||||
margin:0;
|
||||
padding:0;
|
||||
line-height:60px;
|
||||
text-align:center;
|
||||
font-size:24px;
|
||||
color:#5dc2fe;
|
||||
}
|
||||
#currentTime {
|
||||
position:absolute;
|
||||
height:100%;
|
||||
width:35%;
|
||||
line-height:25px;
|
||||
top:2%;
|
||||
left:75%;
|
||||
/*text-align: center;*/
|
||||
font-size:10px;
|
||||
color:#1890FF;
|
||||
}
|
||||
@media (max-width: 1199px) {
|
||||
.header {
|
||||
background:url("../img/header-left.png") left bottom no-repeat, url("../img/header-right.png") right bottom no-repeat;
|
||||
background-size:100%, 100%;
|
||||
}
|
||||
.header h3 {line-height:48px;}
|
||||
}
|
||||
.wrapper {position:absolute;top:70px;bottom:0;left:0;right:0;min-height:555px;}
|
||||
.container-fluid {height:100%;min-height:100%;}
|
||||
.row {margin-left:-7px;margin-right:-8px;}
|
||||
.row>div {padding-left:7px;padding-right:8px;}
|
||||
.xpanel-wrapper {padding-bottom:15px;box-sizing:border-box;}
|
||||
.xpanel-wrapper-1 {height:100%;}
|
||||
.xpanel-wrapper-1-2 {height:50%;}
|
||||
.xpanel-wrapper-1-3 {height:50%;}
|
||||
.xpanel-wrapper-2-3 {height:50%;}
|
||||
.xpanel {
|
||||
position: relative;
|
||||
padding:15px;
|
||||
height:100%;
|
||||
min-height:170px;
|
||||
background:url("../img/panel.png") center no-repeat;
|
||||
background-size:100% 100%;
|
||||
box-sizing:border-box;
|
||||
}
|
||||
.title {
|
||||
position: absolute;
|
||||
padding-left:24px;
|
||||
height:36px;
|
||||
width: 90%;
|
||||
line-height:36px;
|
||||
font-size:15px;
|
||||
font-weight:normal;
|
||||
color:#00C6FB;
|
||||
background-image:url("../img/title-bg.png");
|
||||
background-repeat:no-repeat;
|
||||
background-size:100% 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.center_title {
|
||||
position: absolute;
|
||||
padding-left:24px;
|
||||
height:36px;
|
||||
width: 90%;
|
||||
line-height:36px;
|
||||
font-size:15px;
|
||||
font-weight:normal;
|
||||
color:#00C6FB;
|
||||
background-image:url("../img/title-bg.png");
|
||||
background-repeat:no-repeat;
|
||||
background-size:100% 100%;
|
||||
margin: 0;
|
||||
top:2%;
|
||||
}
|
||||
.title1 {
|
||||
position: absolute;
|
||||
padding-left:15px;
|
||||
height:30px;
|
||||
width: 90%;
|
||||
line-height:15px;
|
||||
font-size:15px;
|
||||
font-weight:normal;
|
||||
color:#FFFFFF;
|
||||
background:none;
|
||||
background-repeat:no-repeat;
|
||||
background-size:100% 100%;
|
||||
margin: 0;
|
||||
}
|
||||
/* tool */
|
||||
.fill-h {height:100%;min-height:100%;}
|
||||
.no-margin {margin:0 !important;}
|
||||
.no-padding {padding:0 !important;}
|
||||
.no-bg {background:none !important;}
|
||||
.no-border {border:0 !important;}
|
||||
.left_right_div {
|
||||
position: absolute;
|
||||
height:79%;
|
||||
width: 93%;
|
||||
top:20%;
|
||||
padding: 0px 0px 0px 0px;
|
||||
background:none;
|
||||
margin: 0;
|
||||
}
|
||||
.center_div {
|
||||
position: absolute;
|
||||
height:88%;
|
||||
width: 100%;
|
||||
top:8%;
|
||||
padding: 0;
|
||||
background:none;
|
||||
margin: 0;
|
||||
}
|
||||
.center_div1 {
|
||||
position: absolute;
|
||||
height:100%;
|
||||
width: 100%;
|
||||
top:5%;
|
||||
padding: 0;
|
||||
background:none;
|
||||
margin: 0;
|
||||
}
|
||||
/* scrollbar */
|
||||
::-webkit-scrollbar {width:0;height:0;}
|
||||
::-webkit-scrollbar-track {background-color:transparent;}
|
||||
::-webkit-scrollbar-thumb {border-radius:5px;background-color:rgba(0, 0, 0, 0.3);}
|
||||
6
数据可视化技术/网店运营大屏(Flask框架)/frontend/css/bootstrap.min.css
vendored
Executable file
7
数据可视化技术/网店运营大屏(Flask框架)/frontend/data/sales_manager.csv
Executable file
@@ -0,0 +1,7 @@
|
||||
sales_manager,sales,profit
|
||||
郝杰,502667.277,55300.637
|
||||
江奕健,179421.48,11725
|
||||
姜伟,222300.092,19919.872
|
||||
王倩倩,691845.854,92687.014
|
||||
杨洪光,761143.054,96180.574
|
||||
张怡莲,558296.522,93976.162
|
||||
|
13
数据可视化技术/网店运营大屏(Flask框架)/frontend/data/sales_month.csv
Executable file
@@ -0,0 +1,13 @@
|
||||
month,sales,profit
|
||||
1月,226678.83,37233.77
|
||||
2月,109855.158,19834.458
|
||||
3月,167173.727,18748.247
|
||||
4月,96984.692,16501.352
|
||||
5月,232199.107,23984.947
|
||||
6月,339729.698,39157.118
|
||||
7月,140050.918,11800.698
|
||||
8月,356128.507,66818.087
|
||||
9月,322759.367,24133.207
|
||||
10月,289269.169,33635.329
|
||||
11月,342142.15,42611.87
|
||||
12月,292702.956,35330.176
|
||||
|
65
数据可视化技术/网店运营大屏(Flask框架)/frontend/data/sales_product.json
Executable file
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"name": "办公用品",
|
||||
"value": 949270.224,
|
||||
"children": [{
|
||||
"name": "标签",
|
||||
"value": 18936.54
|
||||
}, {
|
||||
"name": "美术",
|
||||
"value": 33038.096
|
||||
}, {
|
||||
"name": "器具",
|
||||
"value": 449744.764
|
||||
}, {
|
||||
"name": "收纳具",
|
||||
"value": 214582.2
|
||||
}, {
|
||||
"name": "系固件",
|
||||
"value": 20045.48
|
||||
}, {
|
||||
"name": "信封",
|
||||
"value": 51941.96
|
||||
}, {
|
||||
"name": "用品",
|
||||
"value": 47070.128
|
||||
}, {
|
||||
"name": "纸张",
|
||||
"value": 51413.74
|
||||
},{
|
||||
"name": "装订机",
|
||||
"value": 62497.316
|
||||
}]
|
||||
}, {
|
||||
"name": "技术",
|
||||
"value": 937985.552,
|
||||
"children": [{
|
||||
"name": "电话",
|
||||
"value": 330951.32
|
||||
}, {
|
||||
"name": "复印机",
|
||||
"value": 347513.264
|
||||
}, {
|
||||
"name": "配件",
|
||||
"value": 150562.664
|
||||
}, {
|
||||
"name": "设备",
|
||||
"value": 108958.304
|
||||
}]
|
||||
}, {
|
||||
"name": "家具",
|
||||
"value": 1028418.503,
|
||||
"children": [{
|
||||
"name": "书架",
|
||||
"value": 366969.54
|
||||
}, {
|
||||
"name": "椅子",
|
||||
"value": 409393.054
|
||||
}, {
|
||||
"name": "用具",
|
||||
"value": 83848.996
|
||||
}, {
|
||||
"name": "桌子",
|
||||
"value": 168206.913
|
||||
}]
|
||||
}]
|
||||
31
数据可视化技术/网店运营大屏(Flask框架)/frontend/data/sales_province.csv
Executable file
@@ -0,0 +1,31 @@
|
||||
province,sales,profit
|
||||
安徽,113742.734,32222.834
|
||||
北京,76154.54,19854.24
|
||||
福建,102315.08,32774.7
|
||||
甘肃,47267.444,-13210.036
|
||||
广东,254769.725,58887.605
|
||||
广西,48349.532,14036.932
|
||||
贵州,15893.136,287.616
|
||||
海南,10995.88,4132.94
|
||||
河北,227145.8,43675.38
|
||||
河南,79220.54,17722.6
|
||||
黑龙江,273877.632,66982.132
|
||||
湖北,135006.9,-33492.34
|
||||
湖南,163503.277,31399.277
|
||||
吉林,76539.617,17712.317
|
||||
江苏,128183.776,-16801.764
|
||||
江西,29987.86,7944.72
|
||||
辽宁,152250.028,-29393.812
|
||||
内蒙古,59787.252,-15047.368
|
||||
宁夏,12685.988,-900.592
|
||||
山东,192400.46,49812.56
|
||||
山西,99782.9,25386.9
|
||||
陕西,102767.168,21152.628
|
||||
上海,99893.584,17668.784
|
||||
四川,60567.584,-9514.876
|
||||
天津,95426.03,20107.01
|
||||
西藏,1144.92,400.26
|
||||
新疆,16700.88,4683
|
||||
云南,79432.052,16937.032
|
||||
浙江,94619.56,-27441.26
|
||||
重庆,65262.4,11809.84
|
||||
|
7
数据可视化技术/网店运营大屏(Flask框架)/frontend/data/sales_region.csv
Executable file
@@ -0,0 +1,7 @@
|
||||
region,sales,profit
|
||||
东北,502667.277,55300.637
|
||||
华北,558296.522,93976.162
|
||||
华东,761143.054,96180.574
|
||||
西北,179421.48,11725
|
||||
西南,222300.092,19919.872
|
||||
中南,691845.854,92687.014
|
||||
|
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/bg06.png
Executable file
|
After Width: | Height: | Size: 274 KiB |
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/header-left.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/header-right.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/loading.gif
Executable file
|
After Width: | Height: | Size: 108 KiB |
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/panel.png
Executable file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/thumb.jpg
Executable file
|
After Width: | Height: | Size: 77 KiB |
BIN
数据可视化技术/网店运营大屏(Flask框架)/frontend/img/title-bg.png
Executable file
|
After Width: | Height: | Size: 30 KiB |
77
数据可视化技术/网店运营大屏(Flask框架)/frontend/index.html
Executable file
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
|
||||
<title>网店运营销售数据大屏</title>
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
<script src="js/echarts.min.js"></script>
|
||||
<script src="js/d3.min.js"></script>
|
||||
<script src="js/china.js"></script>
|
||||
</head>
|
||||
|
||||
<body class="bg06">
|
||||
<header class="header">
|
||||
<div id='currentTime'></div>
|
||||
<h3>网店运营销售大屏</h3>
|
||||
</header>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row fill-h">
|
||||
<div class="col-lg-3 fill-h">
|
||||
<div class="xpanel-wrapper xpanel-wrapper-1-2">
|
||||
<div class="xpanel">
|
||||
<div class="title">1-12月各月销售和利润情况</div>
|
||||
<div class="left_right_div" id="data_month"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="xpanel-wrapper xpanel-wrapper-1-2">
|
||||
<div class="xpanel">
|
||||
<div class="title">各产品销售情况</div>
|
||||
<div class="left_right_div" id="data_product"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 fill-h">
|
||||
<div class="xpanel-wrapper xpanel-wrapper-1">
|
||||
<div class="xpanel no-padding no-bg">
|
||||
<div class="center_title">各省份销售和利润情况</div>
|
||||
<div class="center_div">
|
||||
<div class="title1" id="title1"></div>
|
||||
<div class="center_div1" id="data_province"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 fill-h">
|
||||
<div class="xpanel-wrapper xpanel-wrapper-2-3">
|
||||
<div class="xpanel">
|
||||
<div class="title">各地区销售和利润情况</div>
|
||||
<div class="left_right_div" id="data_region"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="xpanel-wrapper xpanel-wrapper-1-3">
|
||||
<div class="xpanel">
|
||||
<div class="title">各产品经理销售和利润情况</div>
|
||||
<div class="left_right_div" id="data_manager"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/totalControl.js"></script>
|
||||
<script>
|
||||
total_control()
|
||||
</script>
|
||||
<script src="js/sales_month.js"></script>
|
||||
<script src="js/sales_product.js"></script>
|
||||
<script src="js/sales_province.js"></script>
|
||||
<script src="js/sales_region.js"></script>
|
||||
<script src="js/sales_manager.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
27
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/china.js
Executable file
2
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/d3.min.js
vendored
Executable file
25
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/echarts.min.js
vendored
Executable file
128
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/sales_manager.js
Executable file
@@ -0,0 +1,128 @@
|
||||
// 发送 AJAX 请求获取数据
|
||||
// 这段代码的作用是从指定的 API 端点(http://127.0.0.1:5000/api/sales_manager)获取销售经理相关的数据,
|
||||
// 并将这些数据整理成三个独立的数组:sales_data、profit_data 和 sales_manager。
|
||||
fetch('http://127.0.0.1:5000/api/sales_manager')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
var sales_data = [];
|
||||
var profit_data = [];
|
||||
var sales_manager = [];
|
||||
data.forEach(item => {
|
||||
temp = {};
|
||||
temp1 = {};
|
||||
temp['value'] = parseFloat(item.sales);
|
||||
temp['name'] = item.sales_manager;
|
||||
temp1['value'] = parseFloat(item.profit);
|
||||
temp1['name'] = item.sales_manager;
|
||||
sales_data.push(temp);
|
||||
profit_data.push(temp1);
|
||||
sales_manager.push(item.sales_manager);
|
||||
});
|
||||
console.log("======sales_manager======");
|
||||
console.log(sales_manager);
|
||||
console.log(sales_data);
|
||||
console.log(profit_data);
|
||||
var myChart = echarts.init(document.getElementById('data_manager'));
|
||||
var option = {
|
||||
color: ["#EAEA26", "#906BF9", "#FE5656", "#01E17E", "#3DD1F9", "#FFAD05"],
|
||||
title: {
|
||||
text: ' 销售情况 利润情况',
|
||||
left: 'left',
|
||||
textStyle: {
|
||||
color: '#0099FF',
|
||||
fontSize: 10,
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
top: 'bottom',
|
||||
data: sales_manager,
|
||||
textStyle: {
|
||||
color: ["#EAEA26", "#906BF9", "#FE5656", "#01E17E", "#3DD1F9", "#FFAD05"],
|
||||
},
|
||||
padding: 0,
|
||||
itemGap: 3,
|
||||
itemWidth: 30,
|
||||
|
||||
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '销售额',
|
||||
type: 'pie',
|
||||
radius: [5, 85],
|
||||
center: ['30%', '50%'],
|
||||
roseType: 'area',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
labelLine: {
|
||||
normal: {
|
||||
show: false,
|
||||
},
|
||||
emphasis: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
data: sales_data,
|
||||
},
|
||||
{
|
||||
name: '利润',
|
||||
type: 'pie',
|
||||
radius: [5, 85],
|
||||
center: ['80%', '50%'],
|
||||
roseType: 'area',
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
labelLine: {
|
||||
normal: {
|
||||
show: false,
|
||||
},
|
||||
emphasis: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
data: profit_data,
|
||||
}
|
||||
]
|
||||
};
|
||||
myChart.setOption(option);
|
||||
var currentIndex = -1;
|
||||
var pie_index = -1;
|
||||
var pie_index1 = 0
|
||||
setInterval(function () {
|
||||
var dataLen = option.series[1].data.length;
|
||||
pie_index = pie_index == 11 ? 0 : (pie_index + 1)
|
||||
// console.log(currentIndex1)
|
||||
// 取消之前高亮的图形
|
||||
myChart.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: pie_index1,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
currentIndex = (currentIndex + 1) % dataLen;
|
||||
pie_index1 = parseInt(pie_index / 6)
|
||||
// 高亮当前图形
|
||||
myChart.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: pie_index1,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
// 显示 tooltip
|
||||
myChart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: pie_index1,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
}, 2000);
|
||||
})
|
||||
190
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/sales_month.js
Executable file
@@ -0,0 +1,190 @@
|
||||
// 发送 AJAX 请求获取数据
|
||||
fetch('http://127.0.0.1:5000/api/sales_month')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
var month = [];
|
||||
var sales = [];
|
||||
var profit = [];
|
||||
data.forEach(item => {
|
||||
month.push(item.month);
|
||||
profit.push(parseFloat((item.profit / 10000).toFixed(2)));
|
||||
sales.push(parseFloat((item.sales / 10000).toFixed(2)));
|
||||
});
|
||||
console.log("======sales_month======")
|
||||
console.log(month);
|
||||
console.log(sales);
|
||||
console.log(profit);
|
||||
var myChart = echarts.init(document.getElementById('data_month'));
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['销售额(万元)', '利润(万元)'],
|
||||
x: 'center',
|
||||
y: 'top',
|
||||
padding: [5, 0, 0, 0],
|
||||
textStyle: {
|
||||
color: '#00F1F3', // 修改为正确的颜色代码
|
||||
fontSize: 10,
|
||||
},
|
||||
itemWidth: 28,
|
||||
itemHeight: 12,
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
left: 0,
|
||||
right: 20,
|
||||
bottom: 0,
|
||||
top: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'line',
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 8,
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#2094CA',
|
||||
type: 'dotted',
|
||||
},
|
||||
},
|
||||
textStyle: {
|
||||
fontSize: 10,
|
||||
},
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
fontSize: 8,
|
||||
color: '#2094CA',
|
||||
},
|
||||
data: month,
|
||||
}],
|
||||
yAxis: [{
|
||||
splitLine: { show: false },
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
fontSize: 8,
|
||||
color: '#2094CA',
|
||||
},
|
||||
}],
|
||||
series: [{
|
||||
name: '销售额(万元)',
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#E78932',
|
||||
},
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#E78932',
|
||||
width: 1,
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'top',
|
||||
textStyle: {
|
||||
color: '#E78932',
|
||||
},
|
||||
fontSize: 8,
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: '#D98234' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: '#33313C' // 100% 处的颜色
|
||||
}],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
opacity: 0.5,
|
||||
},
|
||||
data: sales,
|
||||
showAllSymbol: true,
|
||||
}, {
|
||||
name: '利润(万元)',
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#0099FF',
|
||||
},
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'top',
|
||||
textStyle: {
|
||||
color: '#0099FF',
|
||||
},
|
||||
fontSize: 8,
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#0099FF',
|
||||
width: 0,
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: '#0099FF' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: '#394E7F' // 100% 处的颜色
|
||||
}],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
opacity: 0.3,
|
||||
},
|
||||
data: profit,
|
||||
showAllSymbol: true,
|
||||
}]
|
||||
};
|
||||
myChart.setOption(option);
|
||||
var currentIndex = -1;
|
||||
setInterval(function () {
|
||||
var dataLen = option.series[0].data.length;
|
||||
// 取消之前高亮的图形
|
||||
myChart.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
currentIndex = (currentIndex + 1) % dataLen;
|
||||
// 高亮当前图形
|
||||
myChart.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
// 显示 tooltip
|
||||
myChart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
}, 2000);
|
||||
})
|
||||
.catch(error => console.error('Error fetching data:', error)); // 捕获并处理错误
|
||||
110
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/sales_product.js
Executable file
@@ -0,0 +1,110 @@
|
||||
// 发送 AJAX 请求获取数据
|
||||
fetch('http://127.0.0.1:5000/api/sales_product')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("sales_product"+data)
|
||||
var myChart = echarts.init(document.getElementById('data_product'));
|
||||
var color = [
|
||||
"#00C6FB",
|
||||
"#5781FD",
|
||||
"#4DB1CB",
|
||||
// "#3EBD7C",
|
||||
// "#F7A925",
|
||||
// "#bda29a",
|
||||
// "#ca8622",
|
||||
// "#749f83",
|
||||
// "#6e7074",
|
||||
// "#546570",
|
||||
// "#c4ccd3"
|
||||
];
|
||||
|
||||
option = {
|
||||
tooltip: {
|
||||
// axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
// type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
// },
|
||||
// textStyle:{
|
||||
// color:'#0099FF',
|
||||
// fontSize:10,
|
||||
// }
|
||||
},
|
||||
series: [{
|
||||
name: '销售额',
|
||||
type: 'treemap',
|
||||
roam:false,
|
||||
nodeClick:false,
|
||||
breadcrumb:false,
|
||||
left:0,
|
||||
right:0,
|
||||
top:0,
|
||||
bottom:0,
|
||||
itemStyle: {
|
||||
borderColor: '#062e62'
|
||||
},
|
||||
label:{
|
||||
fontSize:8,
|
||||
color:'#fff',
|
||||
},
|
||||
levels: [{
|
||||
color: color,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
borderWidth: 0,
|
||||
borderColor: '#062e62',
|
||||
gapWidth: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
//colorSaturation: [0.35, 0.6],
|
||||
colorAlpha: [1, 0.5],
|
||||
upperLabel: {
|
||||
normal: {
|
||||
color: '#00C6FB',
|
||||
fontSize:10,
|
||||
show: true,
|
||||
height: 15
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
borderWidth: 5,
|
||||
borderColor: '#062e62',
|
||||
gapWidth: 1,
|
||||
},
|
||||
emphasis: {
|
||||
borderColor: '#ccc'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
leafDepth: 2,
|
||||
data: data
|
||||
}]
|
||||
};
|
||||
//指定的配置项
|
||||
myChart.setOption(option)
|
||||
var currentIndex = -1;
|
||||
setInterval(function () {
|
||||
var dataLen = option.series[0].data.length;
|
||||
// 取消之前高亮的图形
|
||||
myChart.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
currentIndex = (currentIndex + 1) % dataLen;
|
||||
// 高亮当前图形
|
||||
myChart.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
// 显示 tooltip
|
||||
myChart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
}, 1000);
|
||||
})
|
||||
253
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/sales_province.js
Executable file
@@ -0,0 +1,253 @@
|
||||
// 发送 AJAX 请求获取数据
|
||||
fetch('http://127.0.0.1:5000/api/sales_province')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
var sales = [];
|
||||
//将数据整理为地图的数据
|
||||
var sales_province = [];
|
||||
var profit_province = [];
|
||||
data.forEach(item => {
|
||||
sales.push(parseFloat(item.sales));
|
||||
sales_set = {};
|
||||
profit_set = {};
|
||||
sales_set['name'] = item.province;
|
||||
sales_set['value'] = item.sales;
|
||||
profit_set['name'] = item.province;
|
||||
profit_set['value'] = item.profit;
|
||||
sales_province.push(sales_set);
|
||||
profit_province.push(profit_set);
|
||||
});
|
||||
//添加总销售额的数据,用于在图表上方显示
|
||||
var sales_total = Math.round(d3.sum(sales) / 10000);
|
||||
console.log("=======sales_province========");
|
||||
console.log(sales_province);
|
||||
console.log("=======profit_province========");
|
||||
console.log(profit_province);
|
||||
console.log("sales_total:"+sales_total);
|
||||
|
||||
// console.log([sales_province,profit_province])
|
||||
var myChart = echarts.init(document.getElementById('data_province'));
|
||||
var mapName = 'china'
|
||||
var geoCoordMap = {};
|
||||
/*获取地图数据*/
|
||||
myChart.showLoading();
|
||||
var mapFeatures = echarts.getMap(mapName).geoJson.features;
|
||||
myChart.hideLoading();
|
||||
mapFeatures.forEach(function (v) {
|
||||
// 地区名称
|
||||
var name = v.properties.name;
|
||||
// 地区经纬度
|
||||
geoCoordMap[name] = v.properties.cp;
|
||||
|
||||
});
|
||||
var max = 480,
|
||||
min = 9; // todo
|
||||
var maxSize4Pin = 100,
|
||||
minSize4Pin = 20;
|
||||
|
||||
var convertData = function (data) {
|
||||
var res = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var geoCoord = geoCoordMap[data[i].name];
|
||||
if (geoCoord) {
|
||||
res.push({
|
||||
name: data[i].name,
|
||||
value: geoCoord.concat(data[i].value),
|
||||
});
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
option = {
|
||||
// backgroundColor: '#013954',
|
||||
tooltip: {
|
||||
padding: 0,
|
||||
enterable: true,
|
||||
transitionDuration: 1,
|
||||
textStyle: {
|
||||
color: '#000',
|
||||
decoration: 'none',
|
||||
},
|
||||
formatter: function (params) {
|
||||
var tipHtml = '';
|
||||
tipHtml = '<div style="width:180px;height:120px;background:rgba(22,80,158,0.8);border:1px solid rgba(7,166,255,0.7)">'
|
||||
+ '<div style="width:90%;height:30px;line-height:30px;border-bottom:2px solid rgba(7,166,255,0.7);padding:0 10px">' + '<i style="display:inline-block;width:8px;height:8px;background:#16d6ff;border-radius:30px;">' + '</i>'
|
||||
+ '<span style="margin-left:10px;color:#fff;font-size:16px;">' + params.name + '</span>' + '</div>'
|
||||
+ '<div style="padding:10px">'
|
||||
+ '<p style="color:#fff;font-size:12px;">' + '<i style="display:inline-block;width:10px;height:10px;background:#16d6ff;border-radius:40px;margin:0 8px">' + '</i>'
|
||||
+ '销售额:' + '<span style="color:#11ee7d;margin:0 6px;">' + sales_province[params.dataIndex].value + '</span>' + '元' + '</p>'
|
||||
+ '<p style="color:#fff;font-size:12px;">' + '<i style="display:inline-block;width:10px;height:10px;background:#16d6ff;border-radius:40px;margin:0 8px">' + '</i>'
|
||||
+ '利润:' + '<span style="color:#f48225;margin:0 6px;">' + profit_province[params.dataIndex].value + '</span>' + '元' + '</p>'
|
||||
+ '</div>' + '</div>';
|
||||
return tipHtml;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
visualMap: {
|
||||
show: true,
|
||||
min: 0,
|
||||
max: 300000,
|
||||
left: '10%',
|
||||
top: 'bottom',
|
||||
calculable: true,
|
||||
seriesIndex: [1],
|
||||
inRange: {
|
||||
color: ['#04387b', '#467bc0'] // 蓝绿
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
geo: {
|
||||
show: true,
|
||||
map: mapName,
|
||||
label: {
|
||||
normal: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
show: false,
|
||||
}
|
||||
},
|
||||
roam: false,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: '#023677',
|
||||
borderColor: '#1180c7',
|
||||
},
|
||||
emphasis: {
|
||||
areaColor: '#4499d0',
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '散点',
|
||||
type: 'scatter',
|
||||
coordinateSystem: 'geo',
|
||||
data: convertData(profit_province),
|
||||
symbolSize: function (val) {
|
||||
return val[2] / 8000;
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
formatter: '{b}',
|
||||
position: 'right',
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
// animation: false,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'map',
|
||||
map: mapName,
|
||||
geoIndex: 0,
|
||||
aspectScale: 0.5, //长宽比
|
||||
showLegendSymbol: false, // 存在legend时显示
|
||||
label: {
|
||||
normal: {
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
roam: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: '#031525',
|
||||
borderColor: '#FFFFFF',
|
||||
},
|
||||
emphasis: {
|
||||
areaColor: '#2B91B7'
|
||||
}
|
||||
},
|
||||
animation: false,
|
||||
data: sales_province
|
||||
},
|
||||
{
|
||||
name: '点',
|
||||
type: 'scatter',
|
||||
coordinateSystem: 'geo',
|
||||
zlevel: 6,
|
||||
},
|
||||
{
|
||||
name: 'Top 5',
|
||||
type: 'effectScatter',
|
||||
// animation: false,
|
||||
coordinateSystem: 'geo',
|
||||
data: convertData(profit_province),
|
||||
symbolSize: function (val) {
|
||||
return val[2] / 8000;
|
||||
},
|
||||
showEffectOn: 'render',
|
||||
rippleEffect: { //涟漪特效
|
||||
period: 4, //动画时间,值越小速度越快
|
||||
brushType: 'stroke', //波纹绘制方式 stroke, fill
|
||||
scale: 4 //波纹圆环最大限制,值越大波纹越大
|
||||
},
|
||||
hoverAnimation: true,
|
||||
label: {
|
||||
normal: {
|
||||
formatter: '{b}',
|
||||
position: 'left',
|
||||
show: false
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'yellow',
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'yellow'
|
||||
}
|
||||
},
|
||||
zlevel: 1
|
||||
},
|
||||
|
||||
]
|
||||
};
|
||||
myChart.setOption(option)
|
||||
var currentIndex = -1;
|
||||
setInterval(function () {
|
||||
var dataLen = option.series[0].data.length;
|
||||
// 取消之前高亮的图形
|
||||
myChart.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
currentIndex = (currentIndex + 1) % dataLen;
|
||||
// 高亮当前图形
|
||||
myChart.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
// 显示 tooltip
|
||||
myChart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
|
||||
//为id为title1的div添加文字
|
||||
var title1 = document.getElementById("title1");
|
||||
title1.innerHTML = "2023年总销售额是<b style='color:#f48225;font-size:24px'> " + sales_total + " </b>万元" +
|
||||
"<br/><br/>" + "审图号:<b style='color:#ffffff;font-size:14px'> GS(2023)2767号 </b>";
|
||||
title1.style.color = "#467bc0";
|
||||
title1.style.fontSize = "14px";
|
||||
title1.style.fontWeight = "bold"
|
||||
})
|
||||
153
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/sales_region.js
Executable file
@@ -0,0 +1,153 @@
|
||||
// 发送 AJAX 请求获取数据
|
||||
// 这段代码的目的是从指定的 API 端点获取销售区域数据,并将这些数据分解为三个独立的数组:
|
||||
// region(区域名称)、sales(销售额)和 profit(利润)。
|
||||
fetch('http://127.0.0.1:5000/api/sales_region')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
var region=[];
|
||||
var sales=[];
|
||||
var profit=[];
|
||||
data.forEach(item => {
|
||||
region.push(item.region);
|
||||
sales.push(parseFloat(item.sales));
|
||||
profit.push(parseFloat(item.profit));
|
||||
});
|
||||
console.log("======sales_region======")
|
||||
console.log(region);
|
||||
console.log(sales);
|
||||
console.log(profit);
|
||||
// console.log([region,sales,profit])
|
||||
|
||||
var myChart = echarts.init(document.getElementById('data_region'));
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
textStyle:{
|
||||
color:'#0099FF',
|
||||
fontSize:10,
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '2%',
|
||||
right: '4%',
|
||||
bottom: '14%',
|
||||
top:'16%',
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
data: ['销售额', '利润'],
|
||||
right: 10,
|
||||
top:12,
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
fontSize:10,
|
||||
},
|
||||
|
||||
itemWidth: 12,
|
||||
itemHeight: 10,
|
||||
// itemGap: 35
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: region,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'white'
|
||||
|
||||
}
|
||||
},
|
||||
axisLabel:{
|
||||
fontSize:8,
|
||||
color:'#2094CA',
|
||||
},
|
||||
},
|
||||
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'white'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(255,255,255,0.3)'
|
||||
}
|
||||
},
|
||||
axisLabel:{
|
||||
fontSize:8,
|
||||
color:'#2094CA',
|
||||
},
|
||||
},
|
||||
series: [{
|
||||
name: '销售额',
|
||||
type: 'bar',
|
||||
barWidth: '15%',
|
||||
label:{show:false},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: '#fccb05'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: '#f5804d'
|
||||
}]),
|
||||
barBorderRadius: 12,
|
||||
},
|
||||
|
||||
},
|
||||
data:sales,
|
||||
},
|
||||
{
|
||||
name: '利润',
|
||||
type: 'bar',
|
||||
barWidth: '15%',
|
||||
label:{show:false},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: '#8bd46e'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: '#09bcb7'
|
||||
}]),
|
||||
barBorderRadius: 11,
|
||||
}
|
||||
|
||||
},
|
||||
data: profit,
|
||||
}]
|
||||
};
|
||||
var currentIndex = -1;
|
||||
setInterval(function () {
|
||||
var dataLen = option.series[0].data.length;
|
||||
// 取消之前高亮的图形
|
||||
myChart.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
currentIndex = (currentIndex + 1) % dataLen;
|
||||
// 高亮当前图形
|
||||
myChart.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
// 显示 tooltip
|
||||
myChart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
myChart.setOption(option)
|
||||
})
|
||||
32
数据可视化技术/网店运营大屏(Flask框架)/frontend/js/totalControl.js
Executable file
@@ -0,0 +1,32 @@
|
||||
function total_control(){
|
||||
var title_index=0;
|
||||
var time_div=document.getElementById("currentTime");
|
||||
function start(){
|
||||
function getTimeString(){
|
||||
var time=new Date();
|
||||
var hour=time.getHours();
|
||||
var minute=time.getMinutes();
|
||||
var second=time.getSeconds();
|
||||
var year=time.getFullYear();
|
||||
var month=time.getMonth()+1;
|
||||
var day=time.getDate();
|
||||
var week=time.getDay();
|
||||
var weeks=["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
|
||||
// console.log(time)
|
||||
hour=hour<10?'0'+hour:hour;
|
||||
minute=minute<10?'0'+minute:minute;
|
||||
second=second<10?'0'+second:second;
|
||||
day=day<10?'0'+day:day;
|
||||
var currentweek=weeks[week];
|
||||
return year+'年'+month+'月'+day+'日'+' '+currentweek+' '+hour+':'+minute+':'+second;
|
||||
}
|
||||
time_div.innerText=getTimeString();
|
||||
}
|
||||
setInterval(start);
|
||||
window.onload=function(){
|
||||
|
||||
}
|
||||
window.onresize=function(){
|
||||
location.reload(true);
|
||||
}
|
||||
};
|
||||