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

如何在Live Charts中实现柱状图重叠及冷热状态显示

WPF柱状图:Predicted与Cold/Warm柱50%重叠+间隙问题修复

需求&问题

需求

  • 显示Predicted系列的灰色柱状图
  • 根据Temperature值切换显示:
    • 温度<0时显示Cold红色柱
    • 温度>0时显示Warm绿色柱
  • 要求Cold/Warm柱和Predicted柱重叠50%

当前问题

  1. 三个系列的柱子完全分离,无任何重叠效果
  2. 温度为正时,绿色Warm柱旁边会出现红色Cold柱的空白间隙

当前实现代码

XAML代码

<Window x:Class="BarChartOverlap.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <charting:Chart Name="TemperatureChart" Title="Temperature Prediction">
            <charting:ColumnSeries Name="PredictedSeries" Title="Predicted"
                                   ItemsSource="{Binding}"
                                   IndependentValueBinding="{Binding Date}"
                                   DependentValueBinding="{Binding PredictedTemp}"
                                   Background="#FF888888"/>
            <charting:ColumnSeries Name="ColdSeries" Title="Cold"
                                   ItemsSource="{Binding}"
                                   IndependentValueBinding="{Binding Date}"
                                   DependentValueBinding="{Binding ColdTemp}"
                                   Background="#FFFF0000"/>
            <charting:ColumnSeries Name="WarmSeries" Title="Warm"
                                   ItemsSource="{Binding}"
                                   IndependentValueBinding="{Binding Date}"
                                   DependentValueBinding="{Binding WarmTemp}"
                                   Background="#FF00FF00"/>
        </charting:Chart>
    </Grid>
</Window>

C#后台代码

using System;
using System.Collections.Generic;
using System.Windows;

namespace BarChartOverlap
{
    public class TemperatureData
    {
        public DateTime Date { get; set; }
        public double PredictedTemp { get; set; }
        public double ColdTemp { get; set; }
        public double WarmTemp { get; set; }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var data = new List<TemperatureData>
            {
                new TemperatureData { Date = new DateTime(2024, 1, 1), PredictedTemp = 5, ColdTemp = 0, WarmTemp = 5 },
                new TemperatureData { Date = new DateTime(2024, 1, 2), PredictedTemp = -3, ColdTemp = -3, WarmTemp = 0 },
                new TemperatureData { Date = new DateTime(2024, 1, 3), PredictedTemp = 8, ColdTemp = 0, WarmTemp = 8 },
                new TemperatureData { Date = new DateTime(2024, 1, 4), PredictedTemp = -2, ColdTemp = -2, WarmTemp = 0 }
            };
            TemperatureChart.DataContext = data;
        }
    }
}

解决方法

1. 实现50%重叠效果

默认ColumnSeries会给每个系列分配独立横向空间,需手动调整柱宽+偏移实现重叠:

修改XAML配置

给三个系列设置不同PointWidth,再给Cold/Warm系列添加偏移:

<charting:ColumnSeries Name="PredictedSeries" Title="Predicted"
                       ItemsSource="{Binding}"
                       IndependentValueBinding="{Binding Date}"
                       DependentValueBinding="{Binding PredictedTemp}"
                       Background="#FF888888"
                       PointWidth="0.8"/> <!-- 拉宽Predicted柱,预留重叠空间 -->

<charting:ColumnSeries Name="ColdSeries" Title="Cold"
                       ItemsSource="{Binding}"
                       IndependentValueBinding="{Binding Date}"
                       DependentValueBinding="{Binding ColdTemp}"
                       Background="#FFFF0000"
                       PointWidth="0.4"> <!-- Cold/Warm柱宽设为Predicted的一半 -->
    <charting:ColumnSeries.RenderTransform>
        <TranslateTransform X="20"/> <!-- 向右偏移,刚好覆盖Predicted柱的一半 -->
    </charting:ColumnSeries.RenderTransform>
</charting:ColumnSeries>

<charting:ColumnSeries Name="WarmSeries" Title="Warm"
                       ItemsSource="{Binding}"
                       IndependentValueBinding="{Binding Date}"
                       DependentValueBinding="{Binding WarmTemp}"
                       Background="#FF00FF00"
                       PointWidth="0.4">
    <charting:ColumnSeries.RenderTransform>
        <TranslateTransform X="20"/> <!-- 和Cold系列用相同偏移量 -->
    </charting:ColumnSeries.RenderTransform>
</charting:ColumnSeries>

如果需要自适应图表宽度,不要写死X=20,可在后台计算偏移量:

private void TemperatureChart_Loaded(object sender, RoutedEventArgs e)
{
    var categoryAxis = TemperatureChart.ActualAxes.OfType<CategoryAxis>().FirstOrDefault();
    if (categoryAxis == null) return;

    // 计算每个分类的宽度
    double categoryWidth = categoryAxis.ActualWidth / categoryAxis.Categories.Count;
    // 偏移量 = (Predicted柱宽 - Cold/Warm柱宽)/2 * 分类宽度
    double offset = (0.8 - 0.4) * categoryWidth / 2;
    
    (ColdSeries.RenderTransform as TranslateTransform).X = offset;
    (WarmSeries.RenderTransform as TranslateTransform).X = offset;
}

记得给TemperatureChart添加Loaded="TemperatureChart_Loaded"事件。

2. 消除正数值时的红色间隙

间隙是因为Cold系列在温度为正时绑定了0,图表会渲染高度为0的柱子占位。将无效值改为double.NaN,图表会自动忽略这些值:

修改C#数据初始化

var data = new List<TemperatureData>
{
    new TemperatureData { Date = new DateTime(2024, 1, 1), PredictedTemp = 5, ColdTemp = double.NaN, WarmTemp = 5 },
    new TemperatureData { Date = new DateTime(2024, 1, 2), PredictedTemp = -3, ColdTemp = -3, WarmTemp = double.NaN },
    new TemperatureData { Date = new DateTime(2024, 1, 3), PredictedTemp = 8, ColdTemp = double.NaN, WarmTemp = 8 },
    new TemperatureData { Date = new DateTime(2024, 1, 4), PredictedTemp = -2, ColdTemp = -2, WarmTemp = double.NaN }
};

最终效果

修改后:

  • Predicted灰色柱与Cold/Warm柱实现精确50%重叠
  • 温度为正仅显示绿色柱,温度为负仅显示红色柱,无任何空白间隙

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:07:05