C# 图形最大值的四舍五入
我正在绘制一些统计数据,可以是百分比、货币值或普通数字 我需要将graph控件轴的最大值设置为一个漂亮的整数,刚好比数据集中的最大值高一点。(图形控件的默认值不是我想要的) 有两点需要注意:C# 图形最大值的四舍五入,c#,math,C#,Math,我正在绘制一些统计数据,可以是百分比、货币值或普通数字 我需要将graph控件轴的最大值设置为一个漂亮的整数,刚好比数据集中的最大值高一点。(图形控件的默认值不是我想要的) 有两点需要注意: 我为轴最大值设置的值应至少比数据集的最大值高5%(越低越好) 我在0 Y轴上方有4条水平线;因此,理想情况下,Y轴最大值应该很好地除以4 示例数据可能是: 200%, 100%, 100%, 100%, 75%, 50%, 9% 在这种情况下,220%可接受为最大值 $3500161, $1825223,
200%, 100%, 100%, 100%, 75%, 50%, 9%
在这种情况下,220%可接受为最大值
$3500161, $1825223, $1671232, $110112
在这种情况下,3680000美元就可以了。我想是370万美元吧
有人能提出一个很好的公式吗?我可能需要调整设置,例如5%的边距可能更改为10%,或者我可能需要将4条水平线更改为5。对于您的第一次查询使用:
DataView data = new DataView(dt);
string strTarget = dt.Compute("MAX(target)", string.Empty).ToString();// target is your column name.
int tTarget = int.Parse(strTarget.Equals("") ? "0" : strTarget); // Just in case if your string is empty.
myChart.ChartAreas[0].AxisY.Maximum = myChart.ChartAreas[0].AxisY2.Maximum = Math.Ceiling(tTarget * 1.1); // This will give a 10% plus to max value.
对于第二点,我想您可以使用短/长轴交错和偏移属性来解决这一问题。首先,您需要确定(图形顶部)/(最大数据点)的范围。将其下限设为1.05;合理的上限可能是1.1或1.15。范围越宽,图表顶部可能出现的空白越多,但数字可能越“美好”。或者,您可以先选择一个“良好”标准,然后选择最小的足够好的数字,其中上述比率至少为1.05 您还可以通过放宽该下限来提高间隔的“精确性”,例如将其降低到1.02甚至1.0 编辑:回应评论
要找到一个好的最大值,你需要做的是取最大值加上边距,除以区间数,向上取整到最接近的“nice”值,然后乘以区间数。“nice”的合理定义可能是“floor(log_10(max value))-2的倍数”“nice”的更宽松定义将(平均)减少顶部的额外边距。以下是我用于创建图形轴的代码
/// <summary>
/// Axis scales a min/max value appropriately for the purpose of graphs
/// <remarks>Code taken and modified from http://peltiertech.com/WordPress/calculate-nice-axis-scales-in-excel-vba/</remarks>
/// </summary>
public struct Axis
{
public readonly float min_value;
public readonly float max_value;
public readonly float major_step;
public readonly float minor_step;
public readonly int major_count;
public readonly int minor_count;
/// <summary>
/// Initialize Axis from range of values.
/// </summary>
/// <param name="x_min">Low end of range to be included</param>
/// <param name="x_max">High end of range to be included</param>
public Axis(float x_min, float x_max)
{
//Check if the max and min are the same
if(x_min==x_max)
{
x_max*=1.01f;
x_min/=1.01f;
}
//Check if dMax is bigger than dMin - swap them if not
if(x_max<x_min)
{
float temp = x_min;
x_min = x_max;
x_max = temp;
}
//Make dMax a little bigger and dMin a little smaller (by 1% of their difference)
float delta=(x_max-x_min)/2;
float x_mid=(x_max+x_min)/2;
x_max=x_mid+1.01f*delta;
x_min=x_mid-1.01f*delta;
//What if they are both 0?
if(x_max==0&&x_min==0)
{
x_max=1;
}
//This bit rounds the maximum and minimum values to reasonable values
//to chart. If not done, the axis numbers will look very silly
//Find the range of values covered
double pwr=Math.Log(x_max-x_min)/Math.Log(10);
double scl=Math.Pow(10, pwr-Math.Floor(pwr));
//Find the scaling factor
if(scl>0&&scl<=2.5)
{
major_step=0.2f;
minor_step=0.05f;
}
else if(scl>2.5&&scl<5)
{
major_step=0.5f;
minor_step=0.1f;
}
else if(scl>5&&scl<7.5)
{
major_step=1f;
minor_step=0.2f;
}
else
{
major_step=2f;
minor_step=0.5f;
}
this.major_step=(float)(Math.Pow(10, Math.Floor(pwr))*major_step);
this.minor_step=(float)(Math.Pow(10, Math.Floor(pwr))*minor_step);
this.major_count=(int)Math.Ceiling((x_max-x_min)/major_step);
this.minor_count=(int)Math.Ceiling((x_max-x_min)/minor_step);
int i_1=(int)Math.Floor(x_min/major_step);
int i_2=(int)Math.Ceiling(x_max/major_step);
this.min_value=i_1*major_step;
this.max_value=i_2*major_step;
}
public float[] MajorRange
{
get
{
float[] res=new float[major_count+1];
for(int i=0; i<res.Length; i++)
{
res[i]=min_value+major_step*i;
}
return res;
}
}
public float[] MinorRange
{
get
{
float[] res=new float[minor_count+1];
for(int i=0; i<res.Length; i++)
{
res[i]=min_value+minor_step*i;
}
return res;
}
}
}
//
///Axis适当缩放最小/最大值以用于图形
///从中获取和修改的代码http://peltiertech.com/WordPress/calculate-nice-axis-scales-in-excel-vba/
///
公共结构轴
{
公共只读浮点最小值;
公共只读浮点最大值;
公共只读浮动主要步骤;
公共只读浮动小步;
公共只读int主计数;
公共只读整数次计数;
///
///从值的范围初始化轴。
///
///要包括的范围的低端
///包括高端产品
公共轴(最小浮动x_,最大浮动x_)
{
//检查最大值和最小值是否相同
如果(x_min==x_max)
{
x_max*=1.01f;
x_min/=1.01f;
}
//检查dMax是否大于dMin-如果不大于,则交换它们
如果(x#u max0&&scl2.5&&scl5&&scl)这是为什么标记为SQL?您可以在用于生成graph.SQL标记的C#代码中执行此操作。SQL标记已移除,图表控件将自动将Y轴的最小/最大间距设置为正好四分之一(如果指定4)。因此需要找到一个“精确”除以4的数字-这部分我必须自己做(如果我不喜欢他们自动生成的选择)。我之所以说5%,是因为这应该为条形标签留出足够的空间,使其位于条形上方。否则控件会将其放置在条形上。因此它需要在5-10%的范围内。事实上,我刚刚尝试了5%的精确值,这还不够(只是!).仍然不确定如何获得比这个数字更高的整数…是的,我想这大概就是我需要的,虽然我还没有完全理解数学!我必须修改它以使差距更小。但是谢谢!