WPF Devexpress控件库中ChartControl--实现不等距x轴

一、概要

解决问题--ChartControl不等距x轴显示

二、CS代码

用过ChartControl的开发者们应该都知道,ChartControl中设置x轴间距间隔都是固定的数值。

比如(间隔1000)数值为:

0 1000 2000 3000 4000

1  <dxc:AxisY2D.WholeRange>
2            <dxc:Range
3                     MaxValue="0"
4                     MinValue="4000"
5                     SideMarginsValue="0" />
6 </dxc:AxisY2D.WholeRange>

但是,当ChartControl中的某一条数值很小例如值为3,如果不转换的话几乎在控件中看不到用户体验非常不好,解决方案就是实现不等距x轴来显示。

间隔数值可以按照自己的想法来,本文章的数值为:

0 10 100 1000 4000

如果数值设置为不等距,当ChartControl中的某一条数值很小例如值为3的时候,这时候3的数值就可以在0到10这个区间完美显示如图【图a-1】

理想是美好的,那么问题来了,控件实际的间距是固定值1000 而显示间距是0到10这时候怎么转换有人会想0到10的这个域中的值乘以100不就可以满足情况了吗。

是的,这样做可以。但是这个做法非常不科学,因为后面的三个域中的值倍数就不能这么算了。

这时候怎么解决呢?需要用到高中的数学知识分段函数

公式如下:

附加值(总长度*当前段数 / 段数)  第一段附加值为0

((实际值 - 域下限) / (域上限 - 域下限))*(总长度 / 段数)+ 附加值

到这里为止,可能只能大概知道这个公式是个什么情况,但是还是不知道具体为什么要这么算。我们接下来在代码中深入了解。

三、xaml代码

1.修改ChartControl  x轴的显示数值(转换)

1 <local:UpAndDownLabelConverter x:Key="xconv" />
1  <DataTemplate x:Key="AxisYLabelTemplate">
2             <ContentPresenter Content="{Binding Path=Content, Converter={StaticResource xconv}}" />
3 </DataTemplate>
<dxc:AxisY2D.Label>
      <dxc:AxisLabel
              ElementTemplate="{StaticResource AxisYLabelTemplate}"
              Visibility="Visible"
              Visible="True">
      <dxc:Axis2D.ResolveOverlappingOptions>
          <dxc:AxisLabelResolveOverlappingOptions AllowHide="False" />
          </dxc:Axis2D.ResolveOverlappingOptions>
      </dxc:AxisLabel>
</dxc:AxisY2D.Label>

四、算法

  /// <summary>
  /// 推算出显示值
  /// </summary>
  /// <param name="xValue">X轴数值</param>
  /// <param name="minRange">域下限</param>
  /// <param name="maxRange">域上限</param>
  /// <param name="totalLength">总长度</param>
  /// <param name="period">分了几段</param>
  /// <returns></returns>
  private static double RangeCalculate(double xValue, double minRange, double maxRange,double totalLength = 4000.0,int period = 4)
  {
  //实际值 需要转化的实际值
  //域上限 0-10 ,10为上限
  //域下限 0-10 ,0为下限
  //总长度=X轴的上限。例:0 10 100 1000 4000,4000为总长度
  //段数:分了几段 例:0-10,10-100,100-1000,1000-4000 分为4段
  //当前段数:0-10 第1段 , 10-100 第2段 , 100-1000第3段 ,1000-4000第4段
  //段附加值:(总长度 * 当前段数 / 段数) ps:第一段,段附加值为0。附加值是为了值平均
  //分段函数公式:((实际值 - 域下限) / (域上限 - 域下限))*(总长度 / 段数)+ 段附加值

  double x = 0.0;

  if (0 < xValue && xValue <= 10)
  {
  x = ((xValue - minRange) / (maxRange - minRange)) * (totalLength / period) + 0;
  }
  if (10 < xValue && xValue <= 100)
  {
  x = ((xValue - minRange) / (maxRange - minRange)) * (totalLength / period) + (totalLength * 1 / period);
  }
  if (100 < xValue && xValue <= 1000)
  {
  x = ((xValue - minRange) / (maxRange - minRange)) * (totalLength / period) + (totalLength * 2 / period);
  }
  if (1000 < xValue && xValue <= 4000)
  {
  x = ((xValue - minRange) / (maxRange - minRange)) * (totalLength / period) + (totalLength * 3 / period);
  }
  return x;
  }

五、Convert

 1    public class NotEquidistantLabelConverter : IValueConverter
 2     {
 3         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 4         {
 5             int target = 0;
 6 
 7             int.TryParse(value.ToString(), out target);
 8 
 9             if (target <= 10)
10                 return 0;
11             else if (target <= 1000)
12                 return 10;
13             else if (target <= 2000)
14                 return 100;
15             else if (target <= 3000)
16                 return 1000;
17             else if (target <= 4000)
18                 return 4000;
19             return string.Empty;
20         }
21 
22         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
23         {
24             throw new NotImplementedException();
25         }
26     }

原文地址:https://www.cnblogs.com/justzhuzhu/p/7299019.html