feat(数据可视化技术): 添加网店运营大屏前端和后端基础结构

- 新建前端项目配置文件和样式文件
- 创建后端 Flask 应用和数据库连接管理器
- 定义多个 API 路由以获取销售数据
This commit is contained in:
2025-05-19 09:12:20 +08:00
parent 265128110d
commit c61ecd74cd
30 changed files with 9132 additions and 0 deletions

View 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>

View 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);}

File diff suppressed because one or more lines are too long

View 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
1 sales_manager sales profit
2 郝杰 502667.277 55300.637
3 江奕健 179421.48 11725
4 姜伟 222300.092 19919.872
5 王倩倩 691845.854 92687.014
6 杨洪光 761143.054 96180.574
7 张怡莲 558296.522 93976.162

View 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
1 month sales profit
2 1月 226678.83 37233.77
3 2月 109855.158 19834.458
4 3月 167173.727 18748.247
5 4月 96984.692 16501.352
6 5月 232199.107 23984.947
7 6月 339729.698 39157.118
8 7月 140050.918 11800.698
9 8月 356128.507 66818.087
10 9月 322759.367 24133.207
11 10月 289269.169 33635.329
12 11月 342142.15 42611.87
13 12月 292702.956 35330.176

View 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
}]
}]

View 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
1 province sales profit
2 安徽 113742.734 32222.834
3 北京 76154.54 19854.24
4 福建 102315.08 32774.7
5 甘肃 47267.444 -13210.036
6 广东 254769.725 58887.605
7 广西 48349.532 14036.932
8 贵州 15893.136 287.616
9 海南 10995.88 4132.94
10 河北 227145.8 43675.38
11 河南 79220.54 17722.6
12 黑龙江 273877.632 66982.132
13 湖北 135006.9 -33492.34
14 湖南 163503.277 31399.277
15 吉林 76539.617 17712.317
16 江苏 128183.776 -16801.764
17 江西 29987.86 7944.72
18 辽宁 152250.028 -29393.812
19 内蒙古 59787.252 -15047.368
20 宁夏 12685.988 -900.592
21 山东 192400.46 49812.56
22 山西 99782.9 25386.9
23 陕西 102767.168 21152.628
24 上海 99893.584 17668.784
25 四川 60567.584 -9514.876
26 天津 95426.03 20107.01
27 西藏 1144.92 400.26
28 新疆 16700.88 4683
29 云南 79432.052 16937.032
30 浙江 94619.56 -27441.26
31 重庆 65262.4 11809.84

View 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
1 region sales profit
2 东北 502667.277 55300.637
3 华北 558296.522 93976.162
4 华东 761143.054 96180.574
5 西北 179421.48 11725
6 西南 222300.092 19919.872
7 中南 691845.854 92687.014

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View 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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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);
})

View 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)); // 捕获并处理错误

View 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);
})

View 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'>&nbsp;" + sales_total + "&nbsp;</b>万元" +
"<br/><br/>" + "审图号:<b style='color:#ffffff;font-size:14px'>&nbsp;GS(2023)2767号&nbsp;</b>";
title1.style.color = "#467bc0";
title1.style.fontSize = "14px";
title1.style.fontWeight = "bold"
})

View 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)
})

View 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);
}
};