目录
-
- 摘要
- 一、实时监控大屏概述
-
- [1.1 什么是实时监控大屏](#1.1 什么是实时监控大屏)
- [1.2 DolphinDB可视化优势](#1.2 DolphinDB可视化优势)
- [1.3 技术架构](#1.3 技术架构)
- 二、数据推送服务
-
- [2.1 WebSocket推送](#2.1 WebSocket推送)
- [2.2 HTTP API推送](#2.2 HTTP API推送)
- [2.3 定时推送](#2.3 定时推送)
- 三、图表类型与实现
-
- [3.1 实时折线图](#3.1 实时折线图)
- [3.2 实时仪表盘](#3.2 实时仪表盘)
- [3.3 实时柱状图](#3.3 实时柱状图)
- [3.4 实时饼图](#3.4 实时饼图)
- [3.5 实时地图](#3.5 实时地图)
- 四、大屏布局设计
-
- [4.1 布局结构](#4.1 布局结构)
- [4.2 数据接口设计](#4.2 数据接口设计)
- [4.3 前端代码示例](#4.3 前端代码示例)
- 五、工业物联网实战案例
-
- [5.1 智能工厂监控大屏](#5.1 智能工厂监控大屏)
- [5.2 能源管理监控大屏](#5.2 能源管理监控大屏)
- 六、性能优化
-
- [6.1 数据推送优化](#6.1 数据推送优化)
- [6.2 前端优化](#6.2 前端优化)
- 七、最佳实践
-
- [7.1 大屏设计原则](#7.1 大屏设计原则)
- [7.2 数据更新策略](#7.2 数据更新策略)
- 八、总结
- 参考资料
摘要
本文详细介绍如何使用DolphinDB构建实时监控大屏系统。从数据推送到前端展示,从图表设计到大屏布局,逐步带领读者实现完整的可视化解决方案。同时提供工业物联网场景的实战案例,包括设备状态监控、实时告警展示、数据趋势分析等,帮助读者打造专业的数据可视化系统。本文适合从事数据可视化和监控系统的工程师阅读。
一、实时监控大屏概述
1.1 什么是实时监控大屏
实时监控大屏是一种将关键业务指标以可视化方式实时展示的系统:
监控大屏架构
数据源
DolphinDB
数据推送服务
WebSocket
前端大屏
实时图表
告警面板
统计卡片
地图展示
1.2 DolphinDB可视化优势
| 优势 | 说明 |
|---|---|
| 实时推送 | 支持WebSocket实时推送 |
| 高性能 | 毫秒级数据更新 |
| 丰富图表 | 支持多种图表类型 |
| 灵活定制 | 可自定义可视化组件 |
1.3 技术架构
设备/传感器
Kafka/MQTT
DolphinDB
流计算引擎
推送服务
WebSocket
ECharts/D3.js
监控大屏
二、数据推送服务
2.1 WebSocket推送
python
// 创建WebSocket推送服务
def startPushService(port=8899) {
// 创建WebSocket服务
ws = websocket::create(port)
// 定义推送处理函数
def pushHandler(msg) {
// 广播消息到所有客户端
websocket::broadcast(ws, toJson(msg))
}
return ws, pushHandler
}
// 创建流表
share streamTable(1:0, `device_id`timestamp`temperature`humidity`status,
[INT, TIMESTAMP, DOUBLE, DOUBLE, SYMBOL]) as monitor_stream
// 启动推送服务
ws, pushHandler = startPushService(8899)
// 订阅流表,推送到前端
subscribeTable(, "monitor_stream", "push", -1, pushHandler, true)
2.2 HTTP API推送
python
// 创建HTTP推送接口
def registerPushAPI() {
// 注册API端点
addHttpHandler("/api/realtime", def(request) {
// 查询最新数据
data = select top 100 * from monitor_stream order by timestamp desc
return toJson(data)
})
addHttpHandler("/api/stats", def(request) {
// 查询统计数据
stats = select device_id,
avg(temperature) as avg_temp,
max(temperature) as max_temp,
min(temperature) as min_temp,
count(*) as count
from monitor_stream
where timestamp > now() - 3600000
group by device_id
return toJson(stats)
})
}
registerPushAPI()
2.3 定时推送
python
// 定时推送统计数据
def pushStats() {
stats = select device_id,
avg(temperature) as avg_temp,
max(temperature) as max_temp,
count(*) as count
from monitor_stream
where timestamp > now() - 60000
group by device_id
websocket::broadcast(ws, toJson(stats))
}
// 每秒推送一次
scheduleJob("push_stats", "推送统计", pushStats,
00:00, 2024.01.01, 2030.12.31, 'S')
三、图表类型与实现
3.1 实时折线图
python
// 实时温度趋势图数据
def getTemperatureTrend(deviceId, minutes=30) {
return select bar(timestamp, 1m) as time,
avg(temperature) as avg_temp,
max(temperature) as max_temp,
min(temperature) as min_temp
from loadTable("dfs://iot_data", "sensor_data")
where device_id = deviceId
and timestamp > now() - minutes * 60000
group by bar(timestamp, 1m)
order by time
}
// 前端ECharts配置
chart_config = {
"title": {"text": "温度趋势"},
"tooltip": {"trigger": "axis"},
"legend": {"data": ["平均温度", "最高温度", "最低温度"]},
"xAxis": {"type": "category", "data": []},
"yAxis": {"type": "value", "name": "温度(°C)"},
"series": [
{"name": "平均温度", "type": "line", "data": []},
{"name": "最高温度", "type": "line", "data": []},
{"name": "最低温度", "type": "line", "data": []}
]
}
3.2 实时仪表盘
python
// 设备状态仪表盘数据
def getDeviceGauge(deviceId) {
latest = select top 1 temperature, humidity, power, status
from monitor_stream
where device_id = deviceId
order by timestamp desc
return {
"temperature": latest.temperature,
"humidity": latest.humidity,
"power": latest.power,
"status": latest.status
}
}
// 前端ECharts仪表盘配置
gauge_config = {
"series": [{
"type": "gauge",
"detail": {"formatter": "{value}°C"},
"data": [{"value": 25, "name": "温度"}],
"axisLine": {
"lineStyle": {
"color": [
[0.3, "#67e0e3"],
[0.7, "#37a2da"],
[1, "#fd666d"]
]
}
}
}]
}
3.3 实时柱状图
python
// 设备数据量统计
def getDeviceDataCount() {
return select device_id,
count(*) as count
from monitor_stream
where timestamp > now() - 3600000
group by device_id
order by count desc
limit 10
}
// 前端ECharts柱状图配置
bar_config = {
"title": {"text": "设备数据量TOP10"},
"tooltip": {"trigger": "axis"},
"xAxis": {"type": "category", "data": []},
"yAxis": {"type": "value"},
"series": [{
"type": "bar",
"data": [],
"itemStyle": {
"color": "#5470c6"
}
}]
}
3.4 实时饼图
python
// 设备状态分布
def getStatusDistribution() {
return select status,
count(*) as count
from monitor_stream
where timestamp > now() - 3600000
group by status
}
// 前端ECharts饼图配置
pie_config = {
"title": {"text": "设备状态分布"},
"series": [{
"type": "pie",
"radius": "50%",
"data": [],
"emphasis": {
"itemStyle": {
"shadowBlur": 10,
"shadowOffsetX": 0,
"shadowColor": "rgba(0, 0, 0, 0.5)"
}
}
}]
}
3.5 实时地图
python
// 设备地理位置数据
def getDeviceLocations() {
return select device_id,
location_lat,
location_lon,
temperature,
status
from loadTable("dfs://iot_data", "device_info")
where status != "offline"
}
// 前端地图配置(使用高德/百度地图API)
map_config = {
"center": [116.397428, 39.90923],
"zoom": 12,
"markers": [] // 设备标记点
}
四、大屏布局设计
4.1 布局结构
监控大屏布局
顶部标题栏
系统名称
当前时间
告警数量
左侧面板
设备列表
告警列表
统计卡片
中间区域
核心指标
实时图表
地图展示
右侧面板
趋势图
排行榜
状态分布
4.2 数据接口设计
python
// ========== 大屏数据接口 ==========
// 1. 概览数据
def getOverviewData() {
return {
"total_devices": exec count(distinct device_id) from monitor_stream,
"online_devices": exec count(distinct device_id) from monitor_stream where status = "online",
"alert_count": exec count(*) from alert_stream where timestamp > now() - 3600000,
"data_rate": exec count(*) / 60.0 from monitor_stream where timestamp > now() - 60000
}
}
// 2. 设备状态列表
def getDeviceList() {
return select device_id,
last(temperature) as temperature,
last(humidity) as humidity,
last(status) as status,
last(timestamp) as last_update
from monitor_stream
where timestamp > now() - 300000
group by device_id
order by device_id
}
// 3. 告警列表
def getAlertList(limit=20) {
return select top limit * from alert_stream
order by timestamp desc
}
// 4. 实时趋势
def getRealtimeTrend(deviceId, minutes=30) {
return select bar(timestamp, 1m) as time,
avg(temperature) as temperature,
avg(humidity) as humidity
from monitor_stream
where device_id = deviceId
and timestamp > now() - minutes * 60000
group by bar(timestamp, 1m)
order by time
}
// 5. 设备排行榜
def getDeviceRanking() {
return select device_id,
avg(temperature) as avg_temp,
count(*) as data_count
from monitor_stream
where timestamp > now() - 3600000
group by device_id
order by avg_temp desc
limit 10
}
4.3 前端代码示例
html
<!-- 监控大屏HTML结构 -->
<!DOCTYPE html>
<html>
<head>
<title>工业物联网监控大屏</title>
<script src="echarts.min.js"></script>
<style>
.dashboard {
display: grid;
grid-template-columns: 300px 1fr 300px;
grid-template-rows: 60px 1fr;
height: 100vh;
background: #0a1a2e;
color: #fff;
}
.header {
grid-column: 1 / 4;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
background: linear-gradient(to right, #1a3a5e, #0a1a2e);
}
.left-panel, .right-panel {
padding: 20px;
background: rgba(26, 58, 94, 0.5);
}
.center-panel {
padding: 20px;
display: grid;
grid-template-rows: 1fr 2fr 1fr;
gap: 20px;
}
.chart-container {
background: rgba(26, 58, 94, 0.3);
border-radius: 8px;
padding: 15px;
}
.stat-card {
background: linear-gradient(135deg, #1a3a5e, #0a2a4e);
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
}
.stat-value {
font-size: 32px;
font-weight: bold;
color: #00d4ff;
}
.stat-label {
font-size: 14px;
color: #8899aa;
}
</style>
</head>
<body>
<div class="dashboard">
<!-- 顶部标题栏 -->
<div class="header">
<div class="title">工业物联网实时监控大屏</div>
<div class="time" id="currentTime"></div>
<div class="alert-count">告警: <span id="alertCount">0</span></div>
</div>
<!-- 左侧面板 -->
<div class="left-panel">
<div class="stat-card">
<div class="stat-value" id="totalDevices">0</div>
<div class="stat-label">设备总数</div>
</div>
<div class="stat-card">
<div class="stat-value" id="onlineDevices">0</div>
<div class="stat-label">在线设备</div>
</div>
<div class="stat-card">
<div class="stat-value" id="dataRate">0</div>
<div class="stat-label">数据速率(条/秒)</div>
</div>
<div class="chart-container" id="alertList"></div>
</div>
<!-- 中间区域 -->
<div class="center-panel">
<div class="chart-container" id="gaugeCharts"></div>
<div class="chart-container" id="mainChart"></div>
<div class="chart-container" id="mapChart"></div>
</div>
<!-- 右侧面板 -->
<div class="right-panel">
<div class="chart-container" id="trendChart"></div>
<div class="chart-container" id="pieChart"></div>
<div class="chart-container" id="barChart"></div>
</div>
</div>
<script>
// WebSocket连接
const ws = new WebSocket('ws://localhost:8899');
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
updateCharts(data);
};
// 更新图表
function updateCharts(data) {
// 更新统计卡片
document.getElementById('totalDevices').textContent = data.total_devices;
document.getElementById('onlineDevices').textContent = data.online_devices;
document.getElementById('alertCount').textContent = data.alert_count;
document.getElementById('dataRate').textContent = data.data_rate.toFixed(1);
// 更新图表...
}
// 初始化ECharts
const mainChart = echarts.init(document.getElementById('mainChart'));
// 配置图表...
</script>
</body>
</html>
五、工业物联网实战案例
5.1 智能工厂监控大屏
python
// ========== 智能工厂监控大屏后端 ==========
// 1. 创建数据表
share streamTable(1:0,
`device_id`device_name`location`timestamp`temperature`humidity`pressure`vibration`power`status,
[INT, STRING, STRING, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, SYMBOL]
) as factory_stream
share streamTable(1:0,
`alert_id`device_id`timestamp`alert_type`alert_level`message,
[LONG, INT, TIMESTAMP, SYMBOL, INT, STRING]
) as factory_alerts
// 2. 创建聚合引擎
minute_engine = createTimeSeriesEngine(
"factory_minute_engine",
60000, 60000,
<[
avg(temperature) as avg_temp,
max(temperature) as max_temp,
min(temperature) as min_temp,
avg(power) as avg_power,
count(*) as record_count
]>,
factory_stream,
`device_id,
`timestamp
)
// 3. 创建异常检测引擎
alert_engine = createAnomalyDetectionEngine(
"factory_alert_engine",
<[
temperature > 35 : "高温告警",
temperature < 10 : "低温告警",
vibration > 4.0 : "振动异常",
power > 450 : "功率过高"
]>,
factory_stream,
factory_alerts,
`device_id,
`timestamp
)
// 4. 启动WebSocket推送
ws = websocket::create(8899)
def pushFactoryData(msg) {
websocket::broadcast(ws, toJson({
"type": "realtime",
"data": msg
}))
}
subscribeTable(, "factory_stream", "push", -1, pushFactoryData, true)
// 5. 定时推送统计数据
def pushFactoryStats() {
stats = {
"type": "stats",
"overview": getOverviewData(),
"devices": getDeviceList(),
"alerts": getAlertList(20),
"ranking": getDeviceRanking()
}
websocket::broadcast(ws, toJson(stats))
}
scheduleJob("push_stats", "推送统计", pushFactoryStats,
00:00, 2024.01.01, 2030.12.31, 'S')
print("智能工厂监控大屏已启动")
5.2 能源管理监控大屏
python
// ========== 能源管理监控大屏 ==========
// 能源数据流表
share streamTable(1:0,
`meter_id`timestamp`power`voltage`current`power_factor,
[INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, DOUBLE]
) as energy_stream
// 能源聚合引擎
energy_engine = createTimeSeriesEngine(
"energy_agg_engine",
300000, // 5分钟窗口
300000,
<[
sum(power) / 12 as avg_power_kw, // 平均功率(kW)
sum(power) / 12 / 1000 as energy_kwh, // 电量(kWh)
avg(voltage) as avg_voltage,
avg(current) as avg_current,
avg(power_factor) as avg_pf
]>,
energy_stream,
`meter_id,
`timestamp
)
// 能源统计接口
def getEnergyStats() {
return {
"total_power": exec sum(power) / 1000 from energy_stream where timestamp > now() - 60000,
"peak_power": exec max(power) / 1000 from energy_stream where timestamp > now() - 3600000,
"energy_today": exec sum(power) / 12 / 1000 from energy_stream where date(timestamp) = today(),
"avg_pf": exec avg(power_factor) from energy_stream where timestamp > now() - 3600000
}
}
六、性能优化
6.1 数据推送优化
| 优化项 | 说明 | 建议 |
|---|---|---|
| 推送频率 | 数据推送间隔 | 1-5秒 |
| 批量推送 | 合并多条数据 | 批量大小100-1000 |
| 数据压缩 | 压缩传输数据 | 启用gzip |
| 增量推送 | 只推送变化数据 | 减少数据量 |
6.2 前端优化
javascript
// 前端优化示例
// 1. 数据节流
let lastUpdate = 0;
function throttleUpdate(data) {
const now = Date.now();
if (now - lastUpdate > 1000) { // 最多1秒更新一次
updateCharts(data);
lastUpdate = now;
}
}
// 2. 虚拟滚动(大数据量列表)
function renderVirtualList(data, container, itemHeight) {
const visibleCount = Math.ceil(container.clientHeight / itemHeight);
// 只渲染可见区域...
}
// 3. 图表动画优化
const chartOption = {
animation: false, // 关闭动画提升性能
animationDuration: 0
};
七、最佳实践
7.1 大屏设计原则
| 原则 | 说明 |
|---|---|
| 信息层次 | 核心指标突出显示 |
| 色彩搭配 | 深色背景+亮色数据 |
| 动效适度 | 避免过度动画 |
| 响应式 | 支持不同分辨率 |
7.2 数据更新策略
实时数据
统计数据
历史数据
数据更新
更新类型
WebSocket推送
定时轮询
按需加载
1-5秒更新
10-30秒更新
用户触发
八、总结
本文详细介绍了DolphinDB实时监控大屏的实现方法。核心要点如下:
- 数据推送:WebSocket、HTTP API、定时推送
- 图表类型:折线图、仪表盘、柱状图、饼图、地图
- 大屏布局:顶部标题、左右面板、中间核心区域
- 工业应用:智能工厂、能源管理监控大屏
- 性能优化:推送优化、前端优化
- 最佳实践:设计原则、更新策略
思考题:
- 如何设计一个响应式的监控大屏布局?
- 如何优化大数据量场景下的图表渲染性能?
- 如何保证实时数据推送的可靠性?