UniApp + uView UI 系列(三):智能工地管理系统——统计图表与地图轨迹回放

UniApp + uView UI 系列(三):智能工地管理系统——统计图表与地图轨迹回放

在这里插入图片描述

简介

在前两篇文章中,我们已经完成了智能工地管理系统的基本功能开发,包括用户登录、热区地图展示、扫码巡检等模块。本篇将进入可视化数据分析与轨迹还原阶段,通过 ECharts 图表展示巡检数据,并借助 腾讯地图 API 实现轨迹回放功能,为项目管理者提供更全面的决策支持能力。


1. 巡检统计图表

1.1 使用 ECharts 实现巡检数据统计与展示

我们可以通过 echarts-for-weixin(微信小程序版 ECharts)或 uView UI 对接 ECharts 来实现图表展示功能。此处我们假设使用 echarts 组件方式接入。

安装组件:

npm install echarts --save

注册组件并在页面使用:

<template>
  <view class="chart-container">
    <ec-canvas id="mychart-bar" canvas-id="mychart-bar" ec="{{ ecBar }}"></ec-canvas>
  </view>
</template>

<script>
import * as echarts from 'echarts';

export default {
  data() {
    return {
      ecBar: {
        onInit: function(canvas, width, height, dpr) {
          const chart = echarts.init(canvas, null, {
            width: width,
            height: height,
            devicePixelRatio: dpr
          });
          canvas.setChart(chart);

          const option = {
            title: { text: '月度巡检统计' },
            tooltip: {},
            xAxis: { data: ['1月','2月','3月','4月'] },
            yAxis: {},
            series: [
              {
                name: '巡检次数',
                type: 'bar',
                data: [10, 20, 15, 25]
              }
            ]
          };

          chart.setOption(option);
          return chart;
        }
      }
    };
  }
};
</script>

1.2 数据来源与展示方式设计

数据可以通过接口实时获取,例如:

import { getRequest } from '@/utils/request.js';

getRequest('/inspection/stats/monthly')
  .then(res => {
    // 处理数据并更新 ECharts 配置
  });

后端需提供标准的统计接口,例如返回格式:

{
  "labels": ["1月", "2月", "3月"],
  "data": [10, 15, 22]
}

1.3 图表类型扩展(饼图、折线图等)

  • 饼图适用于展示各区域占比
  • 折线图用于趋势分析
  • 多系列柱状图用于对比各组数据

2. 地图轨迹回放

2.1 地图轨迹回放技术原理

地图轨迹回放是通过对历史位置坐标点(含经纬度、时间戳等)进行可视化渲染,并通过动画逐步绘制轨迹线和移动标记点,从而模拟巡检或设备移动过程。

其核心包括:

  • 获取轨迹数据(坐标点数组)
  • 在地图上绘制 Polyline(折线)
  • 以定时器逐点播放轨迹
  • 控制标记点移动实现“回放”效果

2.2 使用腾讯地图 API 实现轨迹回放

引入地图组件

pages.json 中启用地图组件:

{
  "usingComponents": {
    "map": "plugin://tencentMapPlugin/map"
  }
}
页面代码示例
<template>
  <view class="map-container">
    <map
      :longitude="center.longitude"
      :latitude="center.latitude"
      :polyline="polyline"
      :markers="markers"
      scale="16"
      style="width: 100%; height: 600rpx;"
    ></map>
    <view class="btn-group">
      <button @click="startPlayback">开始回放</button>
      <button @click="pausePlayback">暂停</button>
      <button @click="resetPlayback">重置</button>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      trackPoints: [], // 轨迹点数组
      polyline: [],
      markers: [],
      currentIndex: 0,
      timer: null,
      center: { longitude: 113.324520, latitude: 23.099994 }
    };
  },
  onLoad() {
    this.fetchTrackData();
  },
  methods: {
    fetchTrackData() {
      // 假设从接口获取轨迹数据
      this.trackPoints = [
        { longitude: 113.324520, latitude: 23.099994 },
        { longitude: 113.325, latitude: 23.101 },
        { longitude: 113.326, latitude: 23.103 }
      ];

      this.polyline = [{
        points: this.trackPoints,
        color: "#FF0000DD",
        width: 4
      }];

      this.markers = [{
        id: 1,
        longitude: this.trackPoints[0].longitude,
        latitude: this.trackPoints[0].latitude,
        iconPath: "/static/icon-location.png",
        width: 30,
        height: 30
      }];
    },
    startPlayback() {
      if (this.timer) clearInterval(this.timer);
      this.currentIndex = 0;
      this.timer = setInterval(() => {
        if (this.currentIndex >= this.trackPoints.length) {
          clearInterval(this.timer);
          return;
        }
        this.markers[0].longitude = this.trackPoints[this.currentIndex].longitude;
        this.markers[0].latitude = this.trackPoints[this.currentIndex].latitude;
        this.center = { ...this.trackPoints[this.currentIndex] };
        this.currentIndex++;
      }, 1000);
    },
    pausePlayback() {
      clearInterval(this.timer);
    },
    resetPlayback() {
      clearInterval(this.timer);
      this.currentIndex = 0;
      this.markers[0] = {
        ...this.markers[0],
        ...this.trackPoints[0]
      };
    }
  }
};
</script>

<style scoped>
.map-container {
  position: relative;
}
.btn-group {
  display: flex;
  justify-content: space-around;
  margin-top: 20rpx;
}
</style>

2.3 实现轨迹的动态更新与回放控制

你可以扩展上方逻辑,引入:

  • 后端时间轴点同步回放;
  • 支持拖拽滑动条控制时间进度;
  • 增加轨迹颜色变化用于状态标识(如异常点标红);

例如增加滑动条控制:

<slider min="0" :max="trackPoints.length - 1" v-model="currentIndex" @change="onSliderChange"/>
onSliderChange(e) {
  const idx = e.detail.value;
  this.markers[0] = {
    ...this.markers[0],
    ...this.trackPoints[idx]
  };
}

3. 综合运用:统计图表与地图轨迹联动展示

在实际工地管理中,单独展示统计图表或轨迹地图虽能提供局部信息,但结合两者进行联动可视化,不仅能展示宏观趋势,还能追踪微观事件。例如:

  • 点击图表中“某日异常巡检记录”,地图高亮显示对应轨迹;
  • 在地图播放巡检轨迹的过程中,图表实时更新统计信息。

3.1 联动设计思路

我们以“巡检统计 + 地图轨迹”为例,实现如下交互:

操作行为联动反馈
点击图表中某天的巡检数据地图加载该天的轨迹并开始回放
播放轨迹到异常点图表高亮该数据并弹出详情提示
地图结束播放图表标记播放完毕

实现上,主要涉及以下几点:

  • 图表与地图组件共享 selectedDatetrackData 状态
  • onClick 图表条形事件 → 更新地图轨迹数据
  • 地图播放至指定点时,触发回调 → 通知图表组件

3.2 示例实现:点击图表加载轨迹

统一状态管理(可用 Pinia)
// stores/track.js
import { defineStore } from 'pinia';

export const useTrackStore = defineStore('track', {
  state: () => ({
    selectedDate: '',
    chartData: [],
    trackPoints: []
  }),
  actions: {
    setSelectedDate(date) {
      this.selectedDate = date;
    },
    setTrackPoints(points) {
      this.trackPoints = points;
    }
  }
});
图表组件触发事件
// 统计图表组件 methods 中
onChartClick(params) {
  const date = params.name;
  trackStore.setSelectedDate(date);
  this.fetchTrackData(date); // 模拟根据日期加载轨迹数据
},
fetchTrackData(date) {
  getRequest(`/track/by-date?date=${date}`).then(res => {
    trackStore.setTrackPoints(res.data.points);
  });
}
地图组件监听状态更新
watch(() => trackStore.selectedDate, (newDate) => {
  if (newDate) {
    this.initTrack(trackStore.trackPoints);
  }
});

地图组件内部接收到数据后调用 startPlayback() 播放轨迹。


3.3 工地设备状态追踪与事件回溯

除了巡检轨迹,地图回放也可以用于:

  • 设备轨迹追踪:例如吊车、挖掘机、运输车辆的移动历史;
  • 故障事件回溯:结合报警时间点,倒查异常前的移动轨迹和操作位置;
  • 多人巡检合并展示:不同颜色轨迹区分多个工人。
this.trackLines = [
  { id: 1, color: '#FF0000', points: staffAData },
  { id: 2, color: '#00FF00', points: staffBData }
];

通过这种方式,地图可以承载更多维度的数据,成为“工地实时回溯分析”的可视化平台。


4. 总结与后续扩展

通过本篇文章,我们围绕智能工地管理系统中的 统计图表与地图轨迹回放 功能,进行了从实现原理到实战细节的完整解析。以下是本篇的核心内容回顾:

✅ 已实现内容回顾:

  • 使用 ECharts 实现了多样化的巡检统计图表,包括饼图、柱状图等;
  • 通过 腾讯地图 API 实现了巡检人员的轨迹回放功能,支持播放控制与样式自定义;
  • 利用 Pinia 状态管理 实现了图表与地图之间的联动操作,增强了交互体验;
  • 提供了 设备状态追踪事件回溯 的可视化思路,适用于更复杂的工地场景。

🔧 后续扩展建议:

为了进一步增强系统的实用性与可维护性,推荐如下优化方向:

4.1 支持时间轴过滤与多条件联动

可以在地图与图表联动的基础上,增加时间轴组件与筛选条件,实现更加灵活的数据可视化体验。例如:

  • 筛选“设备类型 + 日期 + 区域”后,仅展示符合条件的轨迹与统计;
  • 时间轴联动地图播放,实现跨日数据追踪。
4.2 图表与地图组件解耦优化

当前图表与地图的联动通过共享状态实现,在项目进一步复杂后,可以考虑通过事件总线或 composable hooks 封装交互逻辑,提升组件复用性与隔离性。

4.3 引入图表可下载与导出功能

可结合 html2canvasjspdf 等库实现图表与轨迹截图导出,方便项目汇报或留档。

4.4 回放轨迹加上语音或异常提示

可以在轨迹回放时集成语音播报或者弹窗提示(如“设备在此点异常停留5分钟”),增强信息传达的即时性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈探索者chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值