WinForms/DevExpress分段条形图开发:人员位置时间可视化问题
解决人员-时间个性化分段条形图的方案
嘿,这个问题我之前帮不少人解决过!你要做的其实是个性化分段的人员时间轴条形图,本质是甘特图的简化版,但市面上大部分示例都是基于统一分段类别的(比如所有人都有固定的几个状态),完全不贴合真实场景里每个人位置分段不一样的情况对吧?
下面给你两种常用工具的实现思路,直接就能套用:
一、用Matplotlib实现(适合静态导出)
Matplotlib需要手动处理每个分段的起始位置和长度,核心是把时间转成可计算的数值(比如分钟数),然后逐个绘制每个人员的分段条形:
步骤1:整理数据结构
把每个人的时间段、位置、对应颜色做成字典,不需要统一分段:
people_data = { "张三": [("09:00", "10:30", "办公室", "#4CAF50"), ("10:30", "12:00", "会议室", "#2196F3"), ("13:30", "17:00", "外出", "#FF9800")], "李四": [("08:30", "11:00", "客户公司", "#9C27B0"), ("11:30", "16:00", "办公室", "#4CAF50")], "王五": [("09:00", "17:00", "家远程", "#F44336")] }
步骤2:完整代码示例
import matplotlib.pyplot as plt import matplotlib.patches as mpatches # 把HH:MM转成当日分钟数,方便X轴计算 def time_to_minutes(time_str): h, m = map(int, time_str.split(":")) return h * 60 + m # 数据准备 people_data = { "张三": [("09:00", "10:30", "办公室", "#4CAF50"), ("10:30", "12:00", "会议室", "#2196F3"), ("13:30", "17:00", "外出", "#FF9800")], "李四": [("08:30", "11:00", "客户公司", "#9C27B0"), ("11:30", "16:00", "办公室", "#4CAF50")], "王五": [("09:00", "17:00", "家远程", "#F44336")] } people = list(people_data.keys()) y_pos = range(len(people)) # 每个人员对应Y轴的位置 plt.figure(figsize=(12, 6)) # 遍历每个人员,绘制分段条形 for y, person in zip(y_pos, people): segments = people_data[person] for start_time, end_time, location, color in segments: start_min = time_to_minutes(start_time) end_min = time_to_minutes(end_time) duration = end_min - start_min # 绘制分段条形 plt.barh(y, duration, left=start_min, color=color, edgecolor="white") # 在分段中间添加位置文本,提升可读性 plt.text(start_min + duration/2, y, location, ha="center", va="center", color="white", fontweight="bold") # 设置X轴为时间格式 x_ticks = [time_to_minutes(f"{h}:00") for h in range(8, 18)] x_labels = [f"{h}:00" for h in range(8, 18)] plt.xticks(x_ticks, x_labels) # 设置Y轴显示人员名称 plt.yticks(y_pos, people) # 生成图例(收集所有唯一的位置-颜色对) unique_locations = {} for person_segments in people_data.values(): for seg in person_segments: if seg[2] not in unique_locations: unique_locations[seg[2]] = seg[3] color_patches = [mpatches.Patch(color=color, label=loc) for loc, color in unique_locations.items()] plt.legend(handles=color_patches, bbox_to_anchor=(1.05, 1), loc="upper left") plt.xlabel("时间") plt.ylabel("人员") plt.title("人员位置时间分布") plt.tight_layout() # 自动调整布局防止图例被截断 plt.show()
二、用Plotly实现(适合交互式展示)
Plotly的优势是可以生成交互式图表,鼠标hover能看详情,而且代码更简洁,同样支持个性化分段:
完整代码示例
import plotly.graph_objects as go def time_to_minutes(time_str): h, m = map(int, time_str.split(":")) return h * 60 + m people_data = { "张三": [("09:00", "10:30", "办公室", "#4CAF50"), ("10:30", "12:00", "会议室", "#2196F3"), ("13:30", "17:00", "外出", "#FF9800")], "李四": [("08:30", "11:00", "客户公司", "#9C27B0"), ("11:30", "16:00", "办公室", "#4CAF50")], "王五": [("09:00", "17:00", "家远程", "#F44336")] } fig = go.Figure() # 为每个人员的每个分段添加Bar trace for person in people_data.keys(): segments = people_data[person] for start_time, end_time, location, color in segments: start_min = time_to_minutes(start_time) end_min = time_to_minutes(end_time) duration = end_min - start_min fig.add_trace(go.Bar( y=[person], x=[duration], base=[start_min], # 设置分段的起始位置 name=location, marker=dict(color=color), text=[location], textposition='inside' # 文本放在分段内部 )) # 调整图表布局 x_ticks = [time_to_minutes(f"{h}:00") for h in range(8, 18)] x_labels = [f"{h}:00" for h in range(8, 18)] fig.update_layout( xaxis=dict(tickvals=x_ticks, ticktext=x_labels, title="时间"), yaxis=dict(title="人员"), barmode='stack', # 堆叠条形图 title="人员位置时间分布", legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) ) fig.show()
关键要点总结
- 核心逻辑:不要强制统一分段类别,而是针对每个人员单独处理其分段的起始位置和时长,时间转数值是实现的关键
- 可读性优化:分段内的文本标注要居中,颜色对比要明显
- 图例处理:自动收集所有唯一的位置,避免重复条目
内容的提问来源于stack exchange,提问作者TJH
相关产品推荐
相关产品推荐

