zoukankan      html  css  js  c++  java
  • 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     }

  • 相关阅读:
    Spring Boot----freemark使用
    vue----解决跨域问题
    CSS----精灵图
    Spring MVC----文件上传
    Mybatis----Mybatis使用
    Django url引用异常
    Django ORM异常
    django sqlite3 报错问题
    爬虫 requests的超时和重试
    python 异常 NameError: name 'ModuleNotFoundError' is not defined
  • 原文地址:https://www.cnblogs.com/justzhuzhu/p/7299019.html
Copyright © 2011-2022 走看看