0
点赞
收藏
分享

微信扫一扫

【2】数据可视化:基于 Echarts + Python 实现的动态实时大屏 - 物流大数据


目录

​​精彩案例汇总​​

​​效果展示​​

​​一、 确定需求方案​​

​​1、确定产品上线部署的屏幕LED分辨率​​

​​2、功能模块​​

​​3、部署方式 ​​

​​二、整体架构设计​​

​​三、编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码)​​

​​1、前端html代码:​​

​​2、前端JS代码​​

​​3、后端python代码​​

​​四、上线运行​​

​​五、源码下载​​

​​精彩案例汇总​​

近年来,数据可视化大屏的出现,掀起一番又一番的浪潮,众多企业主纷纷想要打造属于自己的“酷炫吊炸天”的霸道总裁大屏驾驶舱。今天为大家来分享的是 【物流大数据服务平台】

之前小伙伴们建议我出一些视频课程来学习Echarts,这样可以更快上手,所以我就追星赶月的录制了​​《Echarts - 0基础入门课程》Echarts-0基础入门--其他视频教程-编程语言希望小伙伴们多多支持。

精彩案例汇总

YYDatav的数据可视化《精彩案例汇总》_YYDataV的博客

话不多说,开始分享干货,欢迎讨论!

效果展示

【2】数据可视化:基于 Echarts + Python 实现的动态实时大屏 - 物流大数据_python

一、 确定需求方案

1、确定产品上线部署的屏幕LED分辨率

1920px*1080px,F11全屏后占满整屏且无滚动条。其它分辨率也可自适应。

2、功能模块


  • 湖南货物收入
  • 湖南省地图
  • 全国地图
  • 货物周转量
  • 湖南高速公路
  • 湖南省飞机场
  • 湖南省业务量
  • 货物周转量

3、部署方式 

基于免安装可执行程序:支持Windows、Linux、Mac等各种操作系统;将程序复制到服务器上即可,无需其它环境依赖;

观看方式:既可在服务器上直接观看程序界面,也可在远程用浏览器打开播放,例如Chrome浏览器、360浏览器等。

二、整体架构设计

1、前端基于Echarts开源库设计,使用WebStorm编辑器;

2、后端基于Python Web实现,使用Pycharm编辑器;

3、数据传输格式:JSON;

4、数据源类型:目前已支持PostgreSQL、MySQL、Oracle、Microsoft SQL Server、SQLite、Excel表格等,还可以定制HTTP API接口方式或其它类型数据库。

5、数据更新方式:摒弃了前端页面定时拉取的方式(这种方式带来严重的资源浪费),采用后端数据实时更新,实时推送到前端展示;

三、编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码)

1、前端html代码:

<!doctype html>

<html>
<head>
<meta charset="utf-8">
<meta content="*" http-equiv="Access-Control-Allow-Origin"/>
<title>index</title>
<script src="js/jquery.js" type="text/javascript"></script>
<link href="css/comon0.css" rel="stylesheet">
</head>
<script>
$(window).load(function () {
$(".loading").fadeOut()
})

/****/
$(document).ready(function () {
var whei = $(window).width()
$("html").css({fontSize: whei / 20})
$(window).resize(function () {
var whei = $(window).width()
$("html").css({fontSize: whei / 20})
});
});
</script>

<body>
<!--<div class="canvas" style="opacity: .2">-->
<!-- <iframe frameborder="0" src="js/index.html" style="width: 100%; height: 100%"></iframe>-->
<!--</div>-->
<div class="loading">
<div class="loadbox"><img src="picture/loading.gif"> 页面加载中...</div>
</div>
<div class="head">
<h1>案例 - 物流大数据服务平台</h1>
<div class="weather"><!--<img src="picture/weather.png"><span>多云转小雨</span>--><span id="showTime"></span></div>
<script>

var t = null;
t = setTimeout(time, 1000);//开始运行
function time() {
clearTimeout(t);//清除定时器
dt = new Date();
var y = dt.getFullYear();
var mt = dt.getMonth() + 1;
var day = dt.getDate();
var h = dt.getHours();//获取时
var m = dt.getMinutes();//获取分
var s = dt.getSeconds();//获取秒
document.getElementById("showTime").innerHTML = y + "年" + mt + "月" + day + "-" + h + "时" + m + "分" + s + "秒";
//async_data();
t = setTimeout(time, 1000); //设定定时器,循环运行
}

</script>
</div>
<div class="mainbox">
<ul class="clearfix">
<li>
<div class="boxall" style="height: 3.1rem">
<div class="main_title"><img alt="" src="img/t_1.png">湖南货物收入</div>
<div class="allnav" id="echart_1"></div>
<div class="boxfoot"></div>
</div>
<div class="boxall" style="height: 3.15rem">
<div class="main_title">湖南省地图<img alt="" src="img/t_2.png"></div>
<div class="allnav" id="echart_2"></div>
<div class="boxfoot"></div>
</div>
<div class="boxall" style="height: 3.1rem" >

<div class="main_title">
<img alt="" src="img/t_7.png">
湖南省交通
</div>
<div class="main_table t_btn8">
<table id="table_1">
<thead>
<tr>
<th>运营数(辆)</th>
<th>线路总长度(公里)</th>
<th>客运总量(万人次)</th>
<th>日期</th>
</tr>
</thead>
<tbody>
<tr>
<td>21059</td>
<td>26497</td>
<td>184448</td>
<td>2018年</td>
</tr>
<tr>
<td>18777</td>
<td>21140</td>
<td>188808</td>
<td>2017年</td>
</tr>
<tr>
<td>15757</td>
<td>20225</td>
<td>201143</td>
<td>2016年</td>
</tr>
<tr>
<td>17458</td>
<td>19567</td>
<td>202446</td>
<td>2015年</td>
</tr>
<tr>
<td>11323</td>
<td>14562</td>
<td>279854</td>
<td>2014年</td>
</tr>
</tbody>
</table>
</div>
<div class="boxfoot"></div>
</div>
</li>
<li>
<div class="boxall" style="height: 6.5rem">
<div class="main_title">全国地图<img alt="" src="img/t_map.png"></div>
<div class="map4" id="echart_map" ></div>
<div class="boxfoot"></div>
</div>
<div class="boxall" style="height: 3.1rem" >

<div class="main_title" >
<img alt="" src="img/t_7.png">
湖南省业务量
</div>
<div class="main_table t_btn8">
<table id="table_2">
<thead>
<tr>
<th>运营数(辆)</th>
<th>线路总长度(公里)</th>
<th>客运总量(万人次)</th>
<th>日期</th>
</tr>
</thead>
<tbody>
<tr>
<td>21059</td>
<td>26497</td>
<td>184448</td>
<td>2018年</td>
</tr>
<tr>
<td>18777</td>
<td>21140</td>
<td>188808</td>
<td>2017年</td>
</tr>
<tr>
<td>15757</td>
<td>20225</td>
<td>201143</td>
<td>2016年</td>
</tr>
<tr>
<td>17458</td>
<td>19567</td>
<td>202446</td>
<td>2015年</td>
</tr>
<tr>
<td>11323</td>
<td>14562</td>
<td>279854</td>
<td>2014年</td>
</tr>
</tbody>
</table>
</div>
<div class="boxfoot"></div>
</div>
</li>
<li>
<div class="boxall" style="height:3.1rem">
<div class="main_title"><img alt="" src="img/t_4.png">货物周转量</div>
<div class="allnav" id="echart_3"></div>
<div class="boxfoot"></div>
</div>
<div class="boxall" style="height: 3.15rem">
<div class="main_title"> <img alt="" src="img/t_5.png">湖南高速公路</div>
<div class="allnav" id="echart_4"></div>
<div class="boxfoot"></div>
</div>
<div class="boxall" style="height: 3.1rem">
<div class="main_title"><img alt="" src="img/t_6.png">湖南省飞机场</div>
<div class="allnav" id="echart_5"></div>
<div class="boxfoot"></div>
</div>
</li>
</ul>
</div>
<div class="back"></div>


<script src="js/area_echarts.js" type="text/javascript"></script>

<script src="js/jquery-2.2.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/common.js"></script>
<!--<script src="js/dataTool.js"></script>-->

<script src="js/echarts.min.js"></script>

<script src="js/index.js"></script>
<script src="js/china.js"></script>
<script src="js/hunan.js"></script>
</body>
</html>

2、前端JS代码

$(function () {
echart_1();
echart_2();

echart_3();
echart_4();

echart_map();
echart_5();

//echart_1湖南货物收入
function echart_1() {
chart_1_data = [{
value: 900.58,
name: '张家口',
itemStyle: {
normal: {
color: '#f845f1'
}
}
},
{
value: 1100.58,
name: '承德',
itemStyle: {
normal: {
color: '#ad46f3'
}
}
},
{
value: 1200.58,
name: '衡水',
itemStyle: {
normal: {
color: '#5045f6'
}
}
},
{
value: 1300.58,
name: '邢台',
itemStyle: {
normal: {
color: '#4777f5'
}
}
},
{
value: 1400.58,
name: '邯郸',
itemStyle: {
normal: {
color: '#44aff0'
}
}
},
{
value: 1500.58,
name: '保定',
itemStyle: {
normal: {
color: '#45dbf7'
}
}
},
{
value: 1500.58,
name: '秦皇岛',
itemStyle: {
normal: {
color: '#f6d54a'
}
}
},
{
value: 1600.58,
name: '石家庄',
itemStyle: {
normal: {
color: '#f69846'
}
}
},
{
value: 1800,
name: '唐山',
itemStyle: {
normal: {
color: '#ff4343'
}
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
},
{
value: 0,
name: "",
itemStyle: {
normal: {
color: 'transparent'
}
},
label: {
show: false
},
labelLine: {
show: false
}
}
]
// console.log(JSON.stringify( chart_1_data ));
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart_1'));
option = {
//鼠标缩放和平移
roam: true,
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c}万元"
},
legend: {
x: 'center',
y: '15%',
data: ['张家口', '承德', '衡水', '邢台', '邯郸', '保定', '秦皇岛', '石家庄', '唐山'],
icon: 'circle',
textStyle: {
color: '#fff',
}
},
calculable: true,
series: [{
name: '',
type: 'pie',
//起始角度,支持范围[0, 360]
startAngle: 0,
//饼图的半径,数组的第一项是内半径,第二项是外半径
radius: [41, 100.75],
//支持设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度
center: ['50%', '40%'],
//是否展示成南丁格尔图,通过半径区分数据大小。可选择两种模式:
// 'radius' 面积展现数据的百分比,半径展现数据的大小。
// 'area' 所有扇区面积相同,仅通过半径展现数据大小
roseType: 'area',
//是否启用防止标签重叠策略,默认开启,圆环图这个例子中需要强制所有标签放在中心位置,可以将该值设为 false。
avoidLabelOverlap: false,
label: {
normal: {
show: true,
formatter: '{c}万元'
},
emphasis: {
show: true
}
},
labelLine: {
normal: {
show: true,
length2: 1,
},
emphasis: {
show: true
}
},
data: chart_1_data
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
}

//echart_2湖南省地图
function echart_2() {
series_data = [{
name: '长沙市',
value: 100
}, {
name: '株洲市',
value: 96
}, {
name: '湘潭市',
value: 98
}, {
name: '衡阳市',
value: 80
}, {
name: '邵阳市',
value: 88
}, {
name: '岳阳市',
value: 79
}, {
name: '常德市',
value: 77,
}, {
name: '张家界市',
value: 33
}, {
name: '益阳市',
value: 69,
}, {
name: '郴州市',
value: 66
}, {
name: '永州市',
value: 22
}, {
name: '娄底市',
value: 51
}, {
name: '湘西土家族苗族自治州',
value: 44
}, {
name: '怀化市',
value: 9
}];
// console.log(JSON.stringify(data));
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart_2'));
myChart.setOption(option = {
//鼠标缩放和平移
roam: true,
// backgroundColor: '#ffffff',
tooltip: {
trigger: 'item',
formatter: '{b}<br/>{c} (p / km2)'
},

visualMap: {
show: true,
min: 0,
max: 100,
left: 'left',
top: 'bottom',
text: ['高', '低'], // 文本,默认为数值文本
// realtime: true,
calculable: true,
// text文字颜色
textStyle:{
color:'#ffffff',
},
inRange: {
color: ['lightskyblue', 'yellow', 'orangered']
}
},
series: [{
type: 'map',
mapType: 'hunan',
zlevel: 2,
label: {
show: true
},
data: series_data
}]
});

// 使用刚指定的配置项和数据显示图表。
window.addEventListener("resize", function () {
myChart.resize();
});
}

// echart_map中国地图
function echart_map() {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart_map'));

var mapName = 'china'
var data = []
var toolTipData = [];

/*获取地图数据*/
myChart.showLoading();
var mapFeatures = echarts.getMap(mapName).geoJson.features;
myChart.hideLoading();
var geoCoordMap = {
'福州': [119.4543, 25.9222],
'长春': [125.8154, 44.2584],
'重庆': [107.7539, 30.1904],
'西安': [109.1162, 34.2004],
'成都': [103.9526, 30.7617],
'常州': [119.4543, 31.5582],
'北京': [116.4551, 40.2539],
'北海': [109.314, 21.6211],
'海口': [110.3893, 19.8516],
'长沙': [113.019455, 28.200103],
'上海': [121.40, 31.73],
'内蒙古': [106.82, 39.67]
};

var GZData = [
[{
name: '长沙'
}, {
name: '福州',
value: 95
}],
[{
name: '长沙'
}, {
name: '长春',
value: 80
}],
[{
name: '长沙'
}, {
name: '重庆',
value: 70
}],
[{
name: '长沙'
}, {
name: '西安',
value: 60
}],
[{
name: '长沙'
}, {
name: '成都',
value: 50
}],
[{
name: '长沙'
}, {
name: '常州',
value: 40
}],
[{
name: '长沙'
}, {
name: '北京',
value: 30
}],
[{
name: '长沙'
}, {
name: '北海',
value: 20
}],
[{
name: '长沙'
}, {
name: '海口',
value: 10
}],
[{
name: '长沙'
}, {
name: '上海',
value: 80
}],
[{
name: '长沙'
}, {
name: '内蒙古',
value: 80
}]
];

var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var dataItem = data[i];
var fromCoord = geoCoordMap[dataItem[0].name];
var toCoord = geoCoordMap[dataItem[1].name];
if (fromCoord && toCoord) {
res.push({
fromName: dataItem[0].name,
toName: dataItem[1].name,
coords: [fromCoord, toCoord]
});
}
}
return res;
};

var color = ['#c5f80e'];
var series = [];
[
['石家庄', GZData]
].forEach(function (item, i) {
console.log(i, item, item[0], item[1])
series.push({
name: item[0],
type: 'lines',
zlevel: 2,
symbol: ['none', 'arrow'],
symbolSize: 10,
effect: {
show: true,
period: 6,
trailLength: 0,
symbol: 'arrow',
symbolSize: 5
},
lineStyle: {
normal: {
color: color[i],
width: 1,
opacity: 0.6,
curveness: 0.2
}
},
data: convertData(item[1])
}, {
name: item[0],
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 2,
rippleEffect: {
brushType: 'stroke'
},
label: {
normal: {
show: true,
position: 'right',
formatter: '{b}'
}
},
symbolSize: function (val) {
return val[2] / 8;
},
itemStyle: {
normal: {
color: color[i]
}
},
data: item[1].map(function (dataItem) {
v = {
name: dataItem[1].name,
value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value])
};
return v
})

});

});

option = {
//鼠标缩放和平移
roam: true,
tooltip: {
trigger: 'item'
},
geo: {
map: 'china',
label: {
emphasis: {
show: false
}
},
roam: true,
itemStyle: {
normal: {
borderColor: 'rgba(147, 235, 248, 1)',
borderWidth: 1,
areaColor: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [{
offset: 0,
color: 'rgba(175,238,238, 0)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba(47,79,79, .1)' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
shadowColor: 'rgba(128, 217, 248, 1)',
// shadowColor: 'rgba(255, 255, 255, 1)',
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 10
},
emphasis: {
areaColor: '#389BB7',
borderWidth: 0
}
}
},
series: series
};

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});

}

//echart_3货物周转量
function echart_3() {

// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart_3'));

data = [
{
name:'铁路货物',
type:'line',
areaStyle: {},
data:[3961.88, 4233.63, 4183.14, 3633.01, 3704.47]
},
{
name:'国家铁路货物',
type:'line',
areaStyle: {},
data:[3374.76, 3364.76, 3274.76, 3371.82, 3259.87]
},
{
name:'地方铁路货物',
type:'line',
areaStyle: {},
data:[14.77, 15.17, 13.17, 14.56, 15.84]
},
{
name:'合资铁路货物',
type:'line',
areaStyle: {},
data:[686.17,847.26,895.22,865.28,886.72]
},
{
name:'公路货物',
type:'line',
areaStyle: {},
data:[6133.47, 6577.89, 7019.56,6821.48,7294.59]
},
{
name:'水运货物',
type:'line',
areaStyle: {},
data:[509.60, 862.54, 1481.77,1552.79,1333.62]
}
]
// console.log(JSON.stringify(data))
// myChart.clear();
option = {
//鼠标缩放和平移
roam: true,
title: {
text: ''
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['铁路货物', '国家铁路货物', '地方铁路货物', '合资铁路货物', '公路货物', '水运货物'],
textStyle: {
color: '#fff'
},
// top: '8%',
},
grid: {
top: '40%',
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
color: ['#FF4949', '#FFA74D', '#FFEA51', '#4BF0FF', '#44AFF0', '#4E82FF', '#584BFF', '#BE4DFF', '#F845F1'],
xAxis: {
type: 'category',
boundaryGap: false,
data: ['2012年', '2013年', '2014年', '2015年', '2016年'],
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: '#fff'
}
}
},
yAxis: {
name: '亿吨公里',
type: 'value',
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: '#fff'
}
}
},
series: data
};

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
}

//湖南高速公路
function echart_4() {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart_4'));

myChart.setOption({
tooltip : {
trigger: 'item'
},
series: [{
type: 'map',
mapType: 'hunan'
}]
});

var geoCoordMap = {
'怀化': [109.999867, 27.518949],
'吉首': [109.741528, 28.332629],
'张家界': [110.491722, 29.112001],
'常德': [111.701486, 29.076683],
'益阳': [112.348741, 28.544124],
'岳阳': [113.126486, 29.382401],
'长沙': [113.019455, 28.200103],
'株洲': [113.163141, 27.8418],
'湘潭': [112.91977, 27.882141],
'邵阳': [111.467859, 27.21915],
'娄底': [112.012438, 27.745506],
'衡阳': [112.63809, 26.895225],
'永州': [111.577632, 26.460144],
'郴州': [113.039396, 25.81497]
};

var goData = [
[{
name: '张家界'

}, {
id: 1,
name: '常德',
value: 86
}],
[{
name: '吉首'

}, {
id: 1,
name: '常德',
value: 86
}],
[{
name: '常德'

}, {
id: 1,
name: '益阳',
value: 70
}],
[{
name: '益阳'

}, {
id: 1,
name: '长沙',
value: 95
}],
[{
name: '长沙'

}, {
id: 1,
name: '岳阳',
value: 70
}],
[{
name: '长沙'

}, {
id: 1,
name: '湘潭',
value: 80
}],
[{
name: '长沙'

}, {
id: 1,
name: '株洲',
value: 80
}],
[{
name: '长沙'

}, {
id: 1,
name: '衡阳',
value: 80
}],
[{
name: '衡阳'

}, {
id: 1,
name: '郴州',
value: 70
}],
[{
name: '衡阳'

}, {
id: 1,
name: '永州',
value: 70
}],
[{
name: '湘潭'

}, {
id: 1,
name: '娄底',
value: 60
}],
[{
name: '娄底'

}, {
id: 1,
name: '邵阳',
value: 75
}],
[{
name: '邵阳'

}, {
id: 1,
name: '怀化',
value: 75
}],
];
//值控制圆点大小
var backData = [
[{
name: '常德'

}, {
id: 1,
name: '张家界',
value: 80
}],
[{
name: '常德'

}, {
id: 1,
name: '吉首',
value: 66
}],
[{
name: '益阳'

}, {
id: 1,
name: '常德',
value: 86
}],
[{
name: '长沙'

}, {
id: 1,
name: '益阳',
value: 70
}],
[{
name: '岳阳'

}, {
id: 1,
name: '长沙',
value: 95
}],
[{
name: '湘潭'

}, {
id: 1,
name: '长沙',
value: 95
}],
[{
name: '株洲'

}, {
id: 1,
name: '长沙',
value: 95
}],
[{
name: '衡阳'

}, {
id: 1,
name: '长沙',
value: 95
}],
[{
name: '郴州'

}, {
id: 1,
name: '衡阳',
value: 80
}],
[{
name: '永州'

}, {
id: 1,
name: '衡阳',
value: 80
}],
[{
name: '娄底'

}, {
id: 1,
name: '湘潭',
value: 80
}],
[{
name: '邵阳'

}, {
id: 1,
name: '娄底',
value: 60
}],
[{
name: '怀化'

}, {
id: 1,
name: '邵阳',
value: 75
}],
];

var planePath = 'path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z';
var arcAngle = function (data) {
var j, k;
for (var i = 0; i < data.length; i++) {
var dataItem = data[i];
if (dataItem[1].id == 1) {
j = 0.2;
return j;
} else if (dataItem[1].id == 2) {
k = -0.2;
return k;
}
}
}

var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var dataItem = data[i];
var fromCoord = geoCoordMap[dataItem[0].name];
var toCoord = geoCoordMap[dataItem[1].name];
if (dataItem[1].id == 1) {
if (fromCoord && toCoord) {
res.push([{
coord: fromCoord,
}, {
coord: toCoord,
value: dataItem[1].value //线条颜色

}]);
}
} else if (dataItem[1].id == 2) {
if (fromCoord && toCoord) {
res.push([{
coord: fromCoord,
}, {
coord: toCoord
}]);
}
}
}
return res;
};

var color = ['#fff', '#FF1493', '#0000FF'];
var series = [];
[
['1', goData],
['2', backData]
].forEach(function (item, i) {
series.push({
name: item[0],
type: 'lines',
zlevel: 2,
symbol: ['arrow', 'arrow'],
//线特效配置
effect: {
show: true,
period: 6,
trailLength: 0.1,
symbol: 'arrow', //标记类型
symbolSize: 5
},
lineStyle: {
normal: {
width: 1,
opacity: 0.4,
curveness: arcAngle(item[1]), //弧线角度
color: '#fff'
}
},
edgeLabel: {
normal: {
show: true,
textStyle: {
fontSize: 14
},
formatter: function (params) {
var txt = '';
if (params.data.speed !== undefined) {
txt = params.data.speed;
}
return txt;
},
}
},
data: convertData(item[1])
}, {
name: item[0],
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 2,
//波纹效果
rippleEffect: {
period: 2,
brushType: 'stroke',
scale: 3
},
label: {
normal: {
show: true,
color: '#fff',
position: 'right',
formatter: '{b}'
}
},
//终点形象
symbol: 'circle',
//圆点大小
symbolSize: function (val) {

return val[2] / 8;
},
itemStyle: {
normal: {
show: true
}
},
data: item[1].map(function (dataItem) {
return {
name: dataItem[1].name,
value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value])
};
})

});

});


option = {
title: {
text: '',
subtext: '',
left: 'center',
textStyle: {
color: '#fff'
}
},
tooltip: {
trigger: 'item',
formatter: '{b}'
},
//线颜色及飞行轨道颜色
visualMap: {
left: 'left',
top: 'bottom',
text: ['高', '低'], // 文本,默认为数值文本
textStyle:{
color:'#ffffff',
},
// realtime: true,
calculable: true,
color: ['green','red', 'blue']
},
//地图相关设置
geo: {
map: 'hunan',
//视角缩放比例
zoom: 1,
//显示文本样式
label: {
normal: {
show: false, //没有数据的地方不显示文本
textStyle: {
color: '#fff'
}
},
emphasis: {
textStyle: {
color: '#fff'
}
}
},
//鼠标缩放和平移
roam: true,
itemStyle: {
normal: {
// color: '#ddd',
borderColor: 'rgba(147, 235, 248, 1)',
borderWidth: 1,
areaColor: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [{
offset: 0,
color: 'rgba(175,238,238, 0)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba( 47,79,79, .2)' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
shadowColor: 'rgba(128, 217, 248, 1)',
// shadowColor: 'rgba(255, 255, 255, 1)',
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 10
},
emphasis: {
areaColor: '#389BB7',
borderWidth: 0
}
}
},
series: series
//series: []
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});

}

//湖南省飞机场
function echart_5() {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart_5'));

function showProvince() {
var geoCoordMap = {
'长沙黄花国际机场': [113.226512, 28.192929],
'张家界荷花机场': [110.454598, 29.107223],
'常德桃花源机场': [111.651508, 28.921516],
'永州零陵机场': [111.622869, 26.340994],
'怀化芷江机场': [109.714784, 27.44615],
};
var data = [{
name: '长沙黄花国际机场',
value: 100
},
{
name: '张家界荷花机场',
value: 100
},
{
name: '常德桃花源机场',
value: 100
},
{
name: '永州零陵机场',
value: 100
},
{
name: '怀化芷江机场',
value: 100
}
];
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;
};
console.log(JSON.stringify(convertData(data)))
myChart.setOption(option = {
title: {
top: 20,
text: '',
subtext: '',
x: 'center',
textStyle: {
color: '#ccc'
}
},
legend: {
orient: 'vertical',
y: 'bottom',
x: 'right',
data: ['pm2.5'],
textStyle: {
color: '#fff'
}
},
visualMap: {
show: false,
min: 0,
max: 500,
left: 'left',
top: 'bottom',
text: ['高', '低'], // 文本,默认为数值文本
calculable: true,
seriesIndex: [1],
inRange: {}
},
geo: {
show: true,
map: 'hunan',
mapType: 'hunan',
label: {
normal: {},
//鼠标移入后查看效果
emphasis: {
textStyle: {
color: '#fff'
}
}
},
//鼠标缩放和平移
roam: true,
itemStyle: {
normal: {
// color: '#ddd',
borderColor: 'rgba(147, 235, 248, 1)',
borderWidth: 1,
areaColor: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [{
offset: 0,
color: 'rgba(175,238,238, 0)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba( 47,79,79, .2)' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
shadowColor: 'rgba(128, 217, 248, 1)',
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 10
},
emphasis: {
areaColor: '#389BB7',
borderWidth: 0
}
}
},
series: [{
name: 'light',
type: 'map',
coordinateSystem: 'geo',
data: convertData(data),
itemStyle: {
normal: {
color: '#F4E925'
}
}
},
{
name: '点',
type: 'scatter',
coordinateSystem: 'geo',
symbol: 'pin',
symbolSize: function (val) {
var a = (maxSize4Pin - minSize4Pin) / (max - min);
var b = minSize4Pin - a * min;
b = maxSize4Pin - a * max;
return a * val[2] + b;
},
label: {
normal: {
// show: true,
// textStyle: {
// color: '#fff',
// fontSize: 9,
// }
}
},
itemStyle: {
normal: {
color: '#F62157', //标志颜色
}
},
zlevel: 6,
data: convertData(data),
},
{
name: 'light',
type: 'map',
mapType: 'hunan',
geoIndex: 0,
aspectScale: 0.75, //长宽比
showLegendSymbol: false, // 存在legend时显示
label: {
normal: {
show: false
},
emphasis: {
show: false,
textStyle: {
color: '#fff'
}
}
},
roam: true,
itemStyle: {
normal: {
areaColor: '#031525',
borderColor: '#FFFFFF',
},
emphasis: {
areaColor: '#2B91B7'
}
},
animation: false,
data: data
},
{
name: ' ',
type: 'effectScatter',
coordinateSystem: 'geo',
data: convertData(data.sort(function (a, b) {
return b.value - a.value;
}).slice(0, 5)),
symbolSize: function (val) {
return val[2] / 10;
},
showEffectOn: 'render',
rippleEffect: {
brushType: 'stroke'
},
hoverAnimation: true,
label: {
normal: {
formatter: '{b}',
position: 'right',
show: true
}
},
itemStyle: {
normal: {
color: '#05C3F9',
shadowBlur: 10,
shadowColor: '#05C3F9'
}
},
zlevel: 1
},

]
});
}

showProvince();

// 使用刚指定的配置项和数据显示图表。
// myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
}

//点击跳转
// $('#chart_map').click(function () {
// window.location.href = './page/index.html';
// });
// $('.t_btn2').click(function () {
// window.location.href = "./page/index.html?id=2";
// });
// $('.t_btn3').click(function () {
// window.location.href = "./page/index.html?id=3";
// });
// $('.t_btn4').click(function () {
// window.location.href = "./page/index.html?id=4";
// });
// $('.t_btn5').click(function () {
// window.location.href = "./page/index.html?id=5";
// });
// $('.t_btn6').click(function () {
// window.location.href = "./page/index.html?id=6";
// });
// $('.t_btn7').click(function () {
// window.location.href = "./page/index.html?id=7";
// });
// $('.t_btn8').click(function () {
// window.location.href = "./page/index.html?id=8";
// });
// $('.t_btn9').click(function () {
// window.location.href = "./page/index.html?id=9";
// });
});



function async_data_chart_1() {
// 异步加载数据
$.getJSON('json/chart_1.json').done(function (data) {
var myChart = echarts.init(document.getElementById('echart_1'));

ret = myChart.setOption({
series: [{
data: data
}]
});

});//end $.getJSON

}

function async_data_chart_2() {
// 异步加载数据
$.getJSON('json/chart_2.json').done(function (data) {
var myChart = echarts.init(document.getElementById('echart_2'));

ret = myChart.setOption({
series: [{
data: data
}]
});

});//end $.getJSON
}
function async_data_chart_map() {
// 异步加载数据
$.getJSON('json/chart_map_effectScatter.json').done(function (data_effectScatter) {
$.getJSON('json/chart_map_lines.json').done(function (data_lines) {
var myChart = echarts.init(document.getElementById('echart_map'));

ret = myChart.setOption({
series: [{
name: data_lines["name"],
data: data_lines["data"]
}, {
name: data_effectScatter["name"],
data: data_effectScatter["data"]
}]
});
});//end $.getJSON
});//end $.getJSON

}
function async_data_chart_3() {
// 异步加载数据
$.getJSON('json/chart_3.json').done(function (data) {
var myChart = echarts.init(document.getElementById('echart_3'));

myChart.setOption({
legend: data["legend"],
xAxis: data["xAxis"],
yAxis: data["yAxis"],
series: data["series"]

});
});//end $.getJSON

}
function async_data_chart_4() {
// 异步加载数据
$.getJSON('json/chart_4.json').done(function (data) {
var myChart = echarts.init(document.getElementById('echart_4'));

myChart.setOption({
series: data
});

});//end $.getJSON
}
function async_data_chart_5() {
// 异步加载数据
$.getJSON('json/chart_5.json').done(function (data) {
var myChart = echarts.init(document.getElementById('echart_5'));

myChart.setOption({
series: [{data: data},
{data: data},
{data: data},
{data: data}]
});

});//end $.getJSON
}


function genTr(tr_data) {
// tr_data = data["tr"]

var $theadHtml = $("<thead></thead>");
var $trTmp = $("<tr></tr>");
for( var i = 0; i < tr_data.length; i++ ) {
$trTmp.append("<td>" + tr_data[i] + "</td>");
}
$trTmp.appendTo($theadHtml)
return $theadHtml
}

function genTd(td_data){
var $tbodyHtml = $("<tbody></tbody>");
for( var i = 0; i < td_data.length; i++ ) {
//动态创建一个tr行标签,并且转换成jQuery对象
var $trTmp = $("<tr></tr>");
var tdTmp = td_data[i]
//往行里面追加 td单元格
for( var k = 0; k < tdTmp.length; k++ ) {
$trTmp.append("<td>"+ tdTmp[k] +"</td>");
}
// $tbodyHtml.append($trTmp)
$trTmp.appendTo($tbodyHtml)
console.log("td_data %d", i)

}
return $tbodyHtml
}

function async_data_table_1() {
// 异步加载数据
$.getJSON('json/table_1.json').done(function (data) {
$("#table_1").empty();
genTr(data["tr"]).appendTo("#table_1");
genTd(data["td"]).appendTo("#table_1");
});//end $.getJSON

}

function async_data_table_2() {
// 异步加载数据
$.getJSON('json/table_2.json').done(function (data) {
$("#table_2").empty();
genTr(data["tr"]).appendTo("#table_2");
genTd(data["td"]).appendTo("#table_2");
});//end $.getJSON
}

function async_data_table_3() {
// 异步加载数据
$.getJSON('json/table_3.json').done(function (data) {
$("#table_3").empty();
genTr(data["tr"]).appendTo("#table_3");
genTd(data["td"]).appendTo("#table_3");
});//end $.getJSON
}

function async_data() {
async_data_chart_1();
async_data_chart_2();
async_data_chart_map();
async_data_chart_3();
async_data_chart_4();
async_data_chart_5();
async_data_table_1();
async_data_table_2();
async_data_table_3();
}

// async_data();

3、后端python代码

import _thread
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
from pyecharts import Geo
from PyQt5.QtCore import QUrl
from win32api import GetSystemMetrics
from PyQt5 import QtGui
from httpserver import *
from asyncJson import *

class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.loadfinished = False
self.setWindowTitle('大屏展示')
self.showMaximized()
#全屏显示
self.showFullScreen()
self.isFullScreen = True

self.webview = WebEngineView()
self.webview.load(QUrl(index_url))
self.setCentralWidget(self.webview)

QShortcut(QtGui.QKeySequence("Escape"), self, self.Esc)
self.webview.loadFinished.connect(self.SetLoadFinished)

_thread.start_new_thread(HttpServer, ())
_thread.start_new_thread(self.ChangeData, ())

def SetLoadFinished(self):
self.loadfinished = True

#模拟刷新数据
def ChangeData(self):
while 1:
#页面加载完毕再开始刷新数据
if self.loadfinished == False :
# print("self.loadfinished == False")
continue
# print("self.loadfinished == True")
# change_all_json()
change_chart_1()
self.webview.page().runJavaScript("async_data_chart_1()")
change_chart_2()
self.webview.page().runJavaScript("async_data_chart_2()")
change_chart_map()
self.webview.page().runJavaScript("async_data_chart_map()")
time.sleep(1)

change_chart_3()
self.webview.page().runJavaScript("async_data_chart_3()")
change_chart_4()
self.webview.page().runJavaScript("async_data_chart_4()")
time.sleep(1)

change_chart_5()
self.webview.page().runJavaScript("async_data_chart_5()")
change_table(table_1_FILENAME)
self.webview.page().runJavaScript("async_data_table_1()")
change_table(table_2_FILENAME)
self.webview.page().runJavaScript("async_data_table_2()")
change_table(table_3_FILENAME)
self.webview.page().runJavaScript("async_data_table_3()")

time.sleep(1)


#按ESC全屏或缩小
def Esc(self):
if self.isFullScreen == True :
self.isFullScreen = False
#不加这句的话,标题栏就看不到了
self.showNormal()
#设置固定宽高
self.setGeometry(GetSystemMetrics(0)/2, GetSystemMetrics(1)/2, 1280, 768)
#再移动到屏幕中央
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
else:
self.showFullScreen()
self.isFullScreen = True


class WebEngineView(QWebEngineView):
windowList = []

# 重写createwindow()
def createWindow(self, QWebEnginePage_WebWindowType):
new_webview = WebEngineView()
new_window = MainWindow()
new_window.setCentralWidget(new_webview)
#new_window.show()
self.windowList.append(new_window) #注:没有这句会崩溃!!!
return new_webview


if __name__ == "__main__":
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

四、上线运行

​​五、源码下载​​

【源码】数据可视化:基于Echarts+Python实现的动态实时大屏范例2-物流大数据.zip_大屏的酷炫echarts-管理软件文档类资源


注:源码包括​​python​​的webserver + json数据源码 + echarts

启动命令:打开cmd命令行,切换到案例根目录,运行 python httpserver.py

引用:基于互联网大牛的前端改进一下,做了个可执行程序,获取数据后更新到页面上。

精彩案例汇总

YYDatav的数据可视化《精彩案例汇总》_YYDataV的博客

本次分享结束,欢迎讨论!


举报

相关推荐

0 条评论