You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wpf中使用LiveCharts绘制堆叠柱状图求助:新手技术问询

实现WPF LiveCharts堆叠柱状图展示每日活动时间段

嘿,刚上手WPF和LiveCharts的话,这种按天展示时间段状态的堆叠柱状图其实很好实现,我给你梳理一套完整的方案,包含数据模型、ViewModel和XAML代码,直接就能用~

1. 先准备数据模型和ViewModel

首先得把数据结构理清楚,让LiveCharts能轻松绑定我们的每日状态数据。

数据模型类

先创建一个类来存储单天的各状态时长统计:

public class DailyStatusData
{
    public DateTime Date { get; set; }
    public double AbsentHours { get; set; } // 缺席总时长
    public double Activity1Hours { get; set; } // 活动1总时长
    public double Activity2Hours { get; set; } // 活动2总时长
    // 后续新增状态直接加对应属性即可
}

ViewModel(核心逻辑)

ViewModel负责把原始数据转换成LiveCharts需要的系列格式,同时处理轴标签:

using LiveCharts;
using LiveCharts.Wpf;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

public class ActivityChartViewModel
{
    // X轴显示的日期标签(比如"Day1", "Day2")
    public List<string> DateLabels { get; set; }

    // 堆叠柱状图的系列集合
    public SeriesCollection StatusSeries { get; set; }

    // Y轴标签格式化器(显示整数小时)
    public Func<double, string> YAxisLabelFormatter => value => $"{value:F0}h";

    public ActivityChartViewModel()
    {
        // 模拟你给出的需求数据
        var dailyData = new List<DailyStatusData>
        {
            new DailyStatusData
            {
                Date = DateTime.Now.AddDays(-1),
                AbsentHours = 8 + 11, // 0-8点 + 12-23点的缺席时长
                Activity1Hours = 3, // 9-12点的活动1时长
                // 活动2时长为0,当天无该状态
            },
            new DailyStatusData
            {
                Date = DateTime.Now,
                AbsentHours = 10, // 0-10点的缺席时长
                Activity2Hours = 2, // 10-12点的活动2时长
                // 活动1时长为0,当天无该状态
            }
        };

        // 生成X轴标签,也可以改成显示具体日期如"2024-05-20"
        DateLabels = dailyData.Select((d, idx) => $"Day{idx+1}").ToList();

        // 初始化堆叠系列,每个状态对应一个系列
        StatusSeries = new SeriesCollection
        {
            // 缺席系列(红色)
            new StackedColumnSeries
            {
                Title = "缺席",
                Values = new ChartValues<double>(dailyData.Select(d => d.AbsentHours)),
                Fill = Brushes.Red
            },
            // 活动1系列(绿色)
            new StackedColumnSeries
            {
                Title = "活动1",
                Values = new ChartValues<double>(dailyData.Select(d => d.Activity1Hours)),
                Fill = Brushes.Green
            },
            // 活动2系列(黄色)
            new StackedColumnSeries
            {
                Title = "活动2",
                Values = new ChartValues<double>(dailyData.Select(d => d.Activity2Hours)),
                Fill = Brushes.Yellow
            }
        };
    }
}

2. XAML布局(视图部分)

在WPF窗口中添加LiveCharts控件,配置轴参数并绑定数据:

<Window x:Class="WpfLiveChartsDemo.ActivityChartWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        xmlns:local="clr-namespace:WpfLiveChartsDemo"
        Title="每日活动分布" Height="450" Width="800">
    <Window.DataContext>
        <local:ActivityChartViewModel/>
    </Window.DataContext>
    <Grid>
        <lvc:CartesianChart Series="{Binding StatusSeries}" LegendLocation="Right">
            <!-- X轴:绑定日期标签 -->
            <lvc:CartesianChart.AxisX>
                <lvc:Axis Title="日期" Labels="{Binding DateLabels}"/>
            </lvc:CartesianChart.AxisX>
            <!-- Y轴:固定0-24小时,绑定格式化器 -->
            <lvc:CartesianChart.AxisY>
                <lvc:Axis Title="小时" MinValue="0" MaxValue="24" 
                          LabelsFormatter="{Binding YAxisLabelFormatter}"/>
            </lvc:CartesianChart.AxisY>
        </lvc:CartesianChart>
    </Grid>
</Window>

3. 关键细节说明

  • 空白区域(未知状态):如果当天所有状态的时长总和小于24,柱子顶部到24小时刻度的空白部分就代表未知状态,完全符合你的需求~
  • 状态扩展:以后要加新活动状态,只需要在DailyStatusData里新增对应时长属性,再在StatusSeries里添加一个新的StackedColumnSeries就行。
  • 日期格式自定义:如果不想显示"Day1"这种标签,直接修改DateLabels的生成逻辑,比如d.Date.ToString("yyyy-MM-dd")就能显示具体年月日。

4. 注意事项

  • 记得通过NuGet安装LiveCharts.Wpf包,建议选最新稳定版;
  • 如果需要更精细的时间段拆分(比如不合并同一天的同状态时长),可以把每个时间段作为独立数据点处理,但当前合并同状态的方式更简洁直观,适合展示每日分布。

内容的提问来源于stack exchange,提问作者Laminos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:48:51