In the words of programmers, I haven’t released a new package for a long time. Today, I will demonstrate the dynamic real-time drag and drop large screen implemented by Echarts/PyQT/Flask . The key things are said three times: custom drag and drop, custom drag and drop, Custom Drag and Drop! ! !
The emergence of large-screen data visualization has set off a wave after another, and many business owners have wanted to build their own "cool dangling sky" domineering president's large-screen cockpit.
Some friends suggested that I take some video courses to learn Echarts, so that I can get started faster, so I recorded "Echarts - 0 Basic Introductory Course" , hoping to help those in need.
portal
drag and drop effect
Drag and drop slice renderings
1. Determine the demand plan
1. Determine the screen LED resolution for the online deployment of the product
This case is based on 16:9 aspect ratio, F11 full screen display.
2. Deployment method
Install-free executable program: support Windows, Linux, Mac and other operating systems;
2. Overall architecture design
- The front-end chart is designed based on the Echarts open source library and uses the WebStorm editor;
- Front-end layout is implemented based on PyQT Dock Spliter ;
- The backend is implemented based on Python Flask and uses the IDEA editor;
- Data transmission format: JSON;
- Data source type: JSON file is currently used. Adding Mybatis by yourself can support PostgreSQL, MySQL, Oracle, Microsoft SQL Server, SQLite, adding Pandas by yourself to support Excel tables, etc. You can also customize the HTTP API interface method.
- Data update method: use http get polling method . In practical applications, you can also choose to monitor the real-time update of the back-end data and push it to the front-end in real time according to the situation;
3. Coding implementation (key code)
1. Front-end html implementation - Echarts chart style style
Here, each Echarts is separated into an html page in order to be nested into Pyqt's QDockWidget.
This version optimizes the code and separates each Echarts chart into a module. The main page only needs to import the corresponding */loader.js file to realize the Echarts chart, which is very simple.
The effect is as shown in the figure:
The html layout code is as follows:
<body style=" background-color:rgb(11, 18, 39)">
<div id="vue_app" class="container-fluid">
<div id="container_m1" style="height: 100%; width: 100%;">
</div>
</div>
</body>
js rendering echarts code is as follows:
function init_echart_map_china_effectScatter(container) {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById(container), window.gTheme);
var data = [];
var geoCoordMap = {};
option = {
// title: {
// text: "国内销售额分布",
// top: "5%",
// left: "center",
// textStyle: {
// // color: "hsl(200, 86%, 48%)",
// fontSize: "16",
// },
// },
tooltip: {
trigger: "item",
formatter: function (params) {
if (typeof params.value[2] == "undefined") {
return params.name + " : " + params.value;
} else {
return params.name + " : " + params.value[2];
}
},
},
geo: {
map: "china",
layoutCenter: ["50%", "50%"],
zoom: 1.5,
roam: true,
// 地图放大或缩小的尺寸
layoutSize: "100%",
selectedMode: "single",
label: {
emphasis: {
show: false,
},
},
// 地图背景色:蓝色
itemStyle: {
normal: {
areaColor: "#4c60ff",
borderColor: "#002097",
},
emphasis: {
areaColor: "#293fff",
},
},
},
series: [
{
name: "点图",
type: "scatter",
coordinateSystem: "geo",
data: [],
symbolSize: function (val) {
return val[2] / 40;
},
label: {
normal: {
formatter: "{b}",
position: "right",
show: false,
},
emphasis: {
show: true,
},
},
},
{
name: "Top 5",
type: "effectScatter",
coordinateSystem: "geo",
data: [],
symbolSize: function (val) {
return val[2] / 30;
},
showEffectOn: "render",
rippleEffect: {
brushType: "stroke",
},
hoverAnimation: true,
label: {
normal: {
formatter: "{b}",
position: "right",
show: true,
textStyle: {
color: "rgba(255,255,255,.8)",
fontSize: 14,
},
},
},
zlevel: 1,
},
],
};
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
}
js dynamic update data code:
function async_echart_map_china_effectScatter(container, filename) {
$.getJSON(filename).done(function (data) {
var myChart = echarts.init(document.getElementById(container));
myChart.setOption({
series: [
{ data: data },
{
data: data
.sort(function (a, b) {
return b.value[2] - a.value[2];
})
.slice(0, 5),
},
],
});
});
}
2. Back-end Python Flask WEB server
app = Flask(__name__, static_folder="static", template_folder="template")
@app.route('/')
def hello_world():
return 'Hello World!'
# 主程序在这里
if __name__ == "__main__":
# 开启线程,触发动态数据
a = threading.Thread(target=asyncJson.loop)
a.start()
# 开启 flask 服务
app.run(host='0.0.0.0', port=88, debug=True)
3. Drag and drop layout QDockWidget
Use QDockWidget to control mobile floating windows.
Use QSplitter to split window control boundaries.
Use QWebEngineView to load html pages.
# 创建QDockWidget窗口(标题,自身窗口)
dock = QDockWidget(title)
# 实例化QSplitter控件, 并设置初始为水平方向布局
splitter = QSplitter(Qt.Horizontal)
# 向Splitter内添加控件。并设置游戏的初始大小
browser = QWebEngineView()
browser.load(QUrl(url))
splitter.addWidget(browser)
dock.setWidget(splitter)
4. Data communication JSON format
[{"name": "长沙", "value": [113.019455, 28.200103, 661]}, {"name": "海门", "value": [121.15, 31.89, 194]}, {"name": "赤峰", "value": [118.87, 42.28, 161]}, {"name": "鄂尔多斯", "value": [109.781327, 39.608266, 194]}, {"name": "招远", "value": [120.38, 37.35, 835]}, {"name": "舟山", "value": [122.207216, 29.985295, 706]}, {"name": "齐齐哈尔", "value": [123.97, 47.33, 857]}, {"name": "盐城", "value": [120.13, 33.38, 696]}, {"name": "青岛", "value": [120.33, 36.07, 569]}, {"name": "乳山", "value": [121.52, 36.89, 108]}, {"name": "金昌", "value": [102.188043, 38.520089, 732]}, {"name": "泉州", "value": [118.58, 24.93, 649]}]
Fourth, development configuration & code structure description
<!-- 启动server命令 -->
python main.py
<!-- 浏览器中输入网址查看大屏(端口为 main.py 中的 port 参数定义) -->
http://localhost:88/static/xxx/index.html
<!-- 启动dock命令 -->
python dock.py
----------
<!-- 逻辑说明 -->
http 服务器:使用 python flask 框架实现
前端页面布局 index.html 实现方式: 使用bootstrap布局
前端 echarts 图表实现方式:每个图表独立的js文件实现
动态数据 *.json 实现方式:
asyncJson.py 定时修改json数据源(python asyncJson.py )
客户端定时器(setInterval();)定时刷最新数据
调用方式:
需要《点 流向 区域》等地图,只需导入对应目录下的 loader.js 即可
----------
<!-- 更多资料参考我的博客主页 -->
https://yydatav.blog.csdn.net/
<!-- 更多案例参考 -->
https://blog.csdn.net/lildkdkdkjf/article/details/120705616
我的微信号:6550523 欢迎多多交流
5. More cases
This sharing is over, welcome to discuss! QQ WeChat same number: 6550523