_

在开发UIBarChart的过程中,需要绘制Y轴的刻度,数据作图时,纵横坐标轴刻度范围及刻度值的取法,很大程度上取决于数据的分布。对某一组数据,我们很容易就能知道如何选取这些值才能使图画得漂亮。但是要想找到一个通用的算法,用以对任意分布的数据决定这些值,并不是一件容易的事。

在网络上找到几篇算法,选取了其中一篇C#语法的,纪录之。

坐标轴刻度取值算法

地址:https://blog.csdn.net/lweiyue/article/details/91869984

作者:还是叫明

下载:https://download.csdn.net/download/lweiyue/11239639

我们在用代码绘制图表的时候,需要绘制坐标轴,而坐标轴上是有刻度的。假如数据最小值是0.32,最大值是0.65,我们想坐标轴上有11个刻度左右,那是不是每个刻度的间隔就是(0.65-0.32)/10=0.033呢?这样做出来的刻度是这样的:

0.32 0.353 0.386 0.419 0.452 0.485 0.518 0.551 0.584 0.617 0.65

Oh my god! 这样的刻度实在太奇怪了。还是这样的刻度比较正常一点呢:

0.3 0.325 0.35 0.375 0.4 0.425 0.45 0.475 0.5 0.525 0.55 0.575 0.6 0.625 0.65

我们现在就来看看下面这种刻度是怎么生成的。首先举几个例子:

0, 10, 15个刻度

0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8 8.5 9 9.5 10

-2.4, -0.023, 15个刻度

-2.4 -2.2 -2 -1.8 -1.6 -1.4 -1.2 -1 -0.8 -0.6 -0.4 -0.2 0

我们这个算法有以下要求:

(1)输入希望大概有多少个刻度。

(2)最终的刻度数只是接近期望,不一定相同。

1、求出实际间隔

double differ = end - start;
double differ_gap = differ / (expect_num - 1);

这很简单,differ_gap就是实际的刻度间隔。但一般情况下,我们需要把刻度转成10,20,25,50这样的值才会看起来比较自然。

2、求出一个转化指数

我们希望的值(10,20,25,50)都是在10-100之间的,但我们的differ_gap可能是0.2,0.025,5000,我们需要把differ_gap转成step*10^_exponent这样的形式,其中step是10-100之间的数。

double exponent = Math.Log10(differ_gap) - 1;
int _exponent = (int)exponent;
if (exponent < 0 && Math.Abs(exponent) > 1e-8)//处理负指数
{
_exponent--;
}

3、得到10-100之间的数

很简单,就一行代码。

int step = (int)(differ_gap / Math.Pow(10, _exponent));

到这一步,假如原来的间隔是0.065,那step就是65了。但65还不是我们想要的,我们想要的是跟它接近的50。

4、转到标准间隔

标准间隔就是我们上面提到的10,20,25,50,100,下面的代码进行转化:

int[] fix_steps = new int[] { 10, 20, 25, 50, 100 };
int fix_step = 10;
for (int i = fix_steps.Length - 1; i >= 1; i--)
{
if (step > (fix_steps[i] + fix_steps[i - 1]) / 2)
{
fix_step = fix_steps[i];
break;
}
}

我们这里求出的是一个最接近的间隔,例如16,介于10跟20之间,跟20最接近,就用20。也因为这个原因,最终的刻度数只是接近期望的刻度数。

5、求出实际的刻度

也很简单,就一行代码。

degree_gap = fix_step * Math.Pow(, _exponent);

假如最初的间隔是0.065,那现在的degree_gap就变成了我们想要的0.05了。

6、求出新的最小值和最大值

一般情况下,最小值最大值都是刻度的整数倍,而且最小值小于或等于原来的最小值,最大值大于或等于原来的最大值。通过下面的代码,我们得到了新的最小值degree_start和新的最大值degree_end。

double start1 = start / degree_gap;
int start2 = (int)start1;
if (start1 < 0 && Math.Abs(start1 - start2) > 1e-8)
{
start2--;
}
degree_start = start2; double end1 = end / degree_gap;
int end2 = (int)end1;
if (end1 >= 0 && Math.Abs(end1 - end2) > 1e-8)
{
end2++;
}
degree_end = end2;

  

[原创][开源] SunnyUI.Net 开发日志:UIBarChart 坐标轴刻度取值算法的更多相关文章

  1. [原创][开源] SunnyUI.Net 开发日志:ListBox 增加跟随鼠标滑过高亮

    QQ群里,寸目说,ListBox鼠标移动时,当前行需要焦点,我想了想,不难实现啊 不就是在鼠标移动时重绘Item嘛,何况选中的Item已经改了颜色了. 见UIListBox代码: protected ...

  2. 坐标轴刻度取值算法-基于魔数数组-源于echarts的y轴刻度计算需求

    本文链接:https://blog.csdn.net/qq_26909801/article/details/96966372数值型坐标轴刻度计算算法前言算法描述上代码代码运行效果结语前言因实习的公司 ...

  3. [原创][开源] SunnyUI.Net 更新日志

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  4. [原创][开源] SunnyUI.Net 系列文章目录

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  5. [原创][开源]SunnyUI.Net, C# .Net WinForm开源控件库、工具类库、扩展类库、多页面开发框架

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  6. [原创][开源] SunnyUI.Net 字体图标

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  7. [原创][开源] SunnyUI.Net 主题

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  8. [原创][开源] SunnyUI.Net 安装

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  9. [原创][开源] SunnyUI.Net 国际化

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

随机推荐

  1. python3.x 基础一:str字符串方法

    *字符串不能更改值 数据类型字符串str |  capitalize(...)   返回字符串中第一个字母大写 |      S.capitalize() -> str |       |    ...

  2. 关于hadoop3.x MR报错:找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster

    用的apache Hadoop3.X,今天运行MR报错: 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster 关键需要配置两个配置:ma ...

  3. 高效、可维护、组件化的CSS

    如何写出更加高效的CSS? 主要有以下四个关键点: 高效的CSS 可维护的CSS 组件化的CSS hack-free CSS 1.书写高效的CSS代码 * 使用 外联样式 替代行间 样式或者内嵌样式. ...

  4. poj1679最小生成树是否唯一

    http://www.cnblogs.com/kuangbin/p/3147329.html #include<cstdio> #include<cstring> #inclu ...

  5. POJ2758 Checking the Text

    题目链接:https://vjudge.net/problem/POJ-2758 题目大意: 先给出一串原始字符串,在此基础上执行两种操作: 1.在第 p 个字符前添加字符 ch,如果 p 比现字符串 ...

  6. mvc的视图渲染方式

    ModelAndView ModelAndView vm = new ModelAndView(); //封装要显示在试图上的数据 vm.addObject("msg"," ...

  7. MyBatis中的命名空间namespace的作用

    1.定义mapper接口,面向接口编程. 2.在大型项目中,可能存在大量的SQL语句,这时候为每个SQL语句起一个唯一的标识(ID)就变得并不容易了.为了解决这个问题,在MyBatis中,可以为每个映 ...

  8. Pandas读取文件报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start byte

    pandas读取文件时报UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start by ...

  9. Java高级特性之集合

    Java集合框架 一.Java集合框架概述 1.数组与集合的区别: 1)数组长度不可变化而且无法保存具有映射关系的数据:集合类用于保存数量不确定的数据,以及保存具有映射关系的数据. 2)数组元素既可以 ...

  10. Springboot之actuator未授权访问

    copy 子杰的哈,懒的写了 0x01  未授权访问可以理解为需要授权才可以访问的页面由于错误的配置等其他原因,导致其他用户可以直接访问,从而引发各种敏感信息泄露. 0x02 Spring Boot ...