如何在Live Charts中实现柱状图重叠及冷热状态显示
WPF柱状图:Predicted与Cold/Warm柱50%重叠+间隙问题修复
需求&问题
需求
- 显示
Predicted系列的灰色柱状图 - 根据
Temperature值切换显示:- 温度<0时显示Cold红色柱
- 温度>0时显示Warm绿色柱
- 要求Cold/Warm柱和Predicted柱重叠50%
当前问题
- 三个系列的柱子完全分离,无任何重叠效果
- 温度为正时,绿色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
相关产品推荐
相关产品推荐

