在图表中将秒转换为hhh:mm:ss [英] Convert seconds to hhh:mm:ss in a chart

查看:197
本文介绍了在图表中将秒转换为hhh:mm:ss的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MsSql数据库,计算两个日期之间的时间间隔,以秒为单位。这工作正常。我之后在C#中使用此列,并将它们写入数组。



此数组是以后的图表输入。
到目前为止,这很好,但我找不到一种方式来显示秒,格式如hhh:mm:ss,因为时间跨度可以大于24小时。



我尝试ChartArea.AxisY.LabelStyle.Format =hhmmss;但它根本不工作。



有人知道我该怎么做吗?



strong> EDIT:
我以这种方式添加数据:

  chart2.Series.Clear ; 
chart2.ChartAreas.Clear();

系列BoxPlotSeries =新系列();

ChartArea ChartArea2 = new ChartArea();
ChartArea ChartArea3 = new ChartArea();

chart2.ChartAreas.Add(ChartArea2);
chart2.ChartAreas.Add(ChartArea3);
ChartArea2.Name =数据图表区域;
ChartArea3.Name =BoxPlotArea;

BoxPlotSeries.Name =BoxPlotSeries;
BoxPlotSeries.ChartType = SeriesChartType.BoxPlot;
BoxPlotSeries.ChartArea =BoxPlotArea;

chart2.Series.Add(BoxPlotSeries);

系列Input1 = new Series();
Input1.Name =Input1;
Input1.ChartType = SeriesChartType.Point;
Input1.ChartArea =数据图表区;
chart2.Series.Add(Input1);
chart2.Series [Input1]。Points.DataBindY(InputArray);
chart2.ChartAreas [BoxPlotArea]。AxisX.CustomLabels.Add(2,0.0,BoxPlot1);


chart2.Series [BoxPlotSeries] [BoxPlotSeries] =输入1;
chart2.Series [BoxPlotSeries] [BoxPlotShowMedian] =true;
chart2.Series [BoxPlotSeries] [BoxPlotShowUnusualValues] =false;
chart2.Series [BoxPlotSeries] [PointWidth] =0.5;
chart2.Series [BoxPlotSeries]。IsValueShownAsLabel = false;
ChartArea2.Visible = false;
ChartArea3.BackColor = Color.FromArgb(224,224,224);
//我试图以这种方式格式化,但它没有工作
//ChartArea3.AxisY.LabelStyle.Format ={0:HHHmmss};
chart2.ChartAreas [BoxPlotArea]。AxisX.LabelStyle.Angle = -90;

EDIT2:
下面是如何填充输入数组

  int [] InputArray = new int [1000000]; 

int c = 0;
con.Open();
dr = cmd.ExecuteReader();
if(dr.HasRows)
{
while(dr.Read())
{
int n;
if(int.TryParse(dr [0] .ToString(),out n)== true)
{
InputArray [c] = Convert.ToInt32(dr [0] .ToString ());
c ++;
}
}
}
if(c == 0){c = 1; }
Array.Resize(ref InputArray,c - 1);

编辑3:
Boxplot应如下所示结束:



在Excel中,显示小于24小时的格式称为[h] :mm:ss; @



EDIT4:



我几乎设法解决我的问题。我对他的解决方案做了一些调整,并提出了这一点:



在图表代码块中:



值max之前设置。

  ChartArea3.AxisY.MajorTickMark.Interval = addCustomLabels(ChartArea3,BoxPlotSeries,60 * max); 





int addCustomLabels(ChartArea ca,Series series,int interval,int max)
{
int tickNo = 0;
ca.AxisY.CustomLabels.Clear();
if(max / interval> 10)
{
interval =(max / 10) - (max / 10)%(60 * 30)
tickNo =(max / 10) - (max / 10)%(60 * 30);
}
if(max / interval <= 2)
{
interval =(max / 4) - (max / 4)%(60 * 15)
tickNo =(max / 4) - (max / 4)%(60 * 15);
}
for(int i = 0; i {
CustomLabel cl = new CustomLabel();
cl.FromPosition = i - interval / 2;
cl.ToPosition = i + interval / 2;
cl.Text = hhh_mm_ss(i);
ca.AxisY.CustomLabels.Add(cl);
}
return tickNo;
}

我的问题是现在,有时没有轴标签)



有任何人和想法可能是错误的吗?

解决方案

您的任务涉及两部分:




  • 在hhh:mm:ss格式

  • 将它们作为y轴上的标签



没有合适的


I have a MsSql database which calculates the timespan between two dates in seconds. That works fine. I use this column afterwards in C# and write them in an array.

This array is the input for a chart later on. So far this works well, but I cannot find a way to display the seconds in a format like hhh:mm:ss as the timespan can be greater than 24h.

I tried ChartArea.AxisY.LabelStyle.Format = "hhmmss"; but it does not work at all.

Does anybody has an idea how I could do that?

EDIT: I add the data this way:

chart2.Series.Clear();
chart2.ChartAreas.Clear();

Series BoxPlotSeries = new Series();

ChartArea ChartArea2 = new ChartArea();
ChartArea ChartArea3 = new ChartArea();

chart2.ChartAreas.Add(ChartArea2);
chart2.ChartAreas.Add(ChartArea3);
ChartArea2.Name = "Data Chart Area";
ChartArea3.Name = "BoxPlotArea";

BoxPlotSeries.Name = "BoxPlotSeries";
BoxPlotSeries.ChartType = SeriesChartType.BoxPlot;
BoxPlotSeries.ChartArea = "BoxPlotArea";

chart2.Series.Add(BoxPlotSeries);

Series Input1 = new Series();
Input1.Name = "Input1";
Input1.ChartType = SeriesChartType.Point;
Input1.ChartArea = "Data Chart Area";
chart2.Series.Add(Input1);
chart2.Series["Input1"].Points.DataBindY(InputArray);
chart2.ChartAreas["BoxPlotArea"].AxisX.CustomLabels.Add(2, 0.0, "BoxPlot1");


chart2.Series["BoxPlotSeries"]["BoxPlotSeries"] = "Input1";
chart2.Series["BoxPlotSeries"]["BoxPlotShowMedian"] = "true";
chart2.Series["BoxPlotSeries"]["BoxPlotShowUnusualValues"] = "false";
chart2.Series["BoxPlotSeries"]["PointWidth"] = "0.5";
chart2.Series["BoxPlotSeries"].IsValueShownAsLabel = false;
ChartArea2.Visible = false;
ChartArea3.BackColor = Color.FromArgb(224,224,224);
//I tried to format it this way but it didn't work
//ChartArea3.AxisY.LabelStyle.Format = "{0:HHHmmss}";
chart2.ChartAreas["BoxPlotArea"].AxisX.LabelStyle.Angle = -90;

EDIT2: And here's how I populate the input array

int[] InputArray = new int[1000000];

int c = 0;
con.Open();
dr = cmd.ExecuteReader();
if (dr.HasRows)         
{
     while (dr.Read())
     {
          int n;
          if (int.TryParse(dr[0].ToString(),out n) == true)
          {
               InputArray[c] = Convert.ToInt32(dr[0].ToString());
               c++;
          }
     }
}
if (c == 0) { c = 1; }
Array.Resize(ref InputArray, c - 1);

EDIT 3: The Boxplot should look like this in the end:

In Excel the format to display hours greater than 24 is called "[h]:mm:ss;@"

EDIT4:

Thanks to @TAW I nearly managed to solve my problem. I made some adjustments to his solution and came up with this:

In the chart code block:

The Value "max" is set before.

    ChartArea3.AxisY.MajorTickMark.Interval = addCustomLabels(ChartArea3, BoxPlotSeries, 60 * 60, max);





 int addCustomLabels(ChartArea ca, Series series, int interval, int max)
    {
        int tickNo = 0;
        ca.AxisY.CustomLabels.Clear();
        if(max / interval > 10)
        {
            interval = (max / 10) - (max / 10) % (60*30);
            tickNo = (max / 10) - (max / 10) % (60*30);
        }
        if (max / interval <= 2 )
        {
            interval = (max / 4) - (max / 4) % (60 * 15);
            tickNo = (max / 4) - (max / 4) % (60 * 15);
        }
        for (int i = 0; i < max; i += interval)
        {
        CustomLabel cl = new CustomLabel();
        cl.FromPosition = i - interval / 2;
        cl.ToPosition = i + interval / 2;
        cl.Text = hhh_mm_ss(i);
        ca.AxisY.CustomLabels.Add(cl);
        }
        return tickNo;
    }

My problem is now, that sometimes no axis lable (apart from 0:00) is shown even when the code runs through it without any problems.

Has anybody and idea what could be wrong?

解决方案

Your task involves two parts:

  • displaying seconds in the hhh:mm:ss format
  • putting them as labels on the y-axis

There is no suitable date-time formatting string for this in c#, so we can't make use of the built-in automatic labels and their formatting.

There also no way to use expressions that call a function on the automatic labels, unfortunately.

So we can't use those.

Instead we will have to add CustomLabels. This is not very hard but does take a few steps..

But let's start with a function that converts an int to the hhh:mm:ss string we want; this should do the job:

string hhh_mm_ss(int seconds)
{
    int sec = seconds % 60;
    int min = ((seconds - sec)/60) % 60;
    int hhh = (seconds - sec - 60 * min) / 3600;
    return hhh > 0 ? string.Format("{2}:{1:00}:{0:00}", sec, min, hhh) 
                   : min + ":" + sec.ToString("00");
}

Maybe it can be optimized, but for our purpose it'll do.

Next we need to create the CustomLabels. They will replace the normal axis labels and we need to add them in a separate loop over the data after each binding.

One special thing about them is their positioning. Which is smack between two values we need to give them, the FromPosition and ToPosition, both in the unit of the axis-values.

Another difference to normal, automatic Labels is that it is up to us to create as many or few of them as need need..

This function tries to create a number that will go up to the maximum y-value and space the CustomLabels at a given interval:

void addCustomLabels(ChartArea ca, Series series, int interval)
{
    // we get the maximum form the 1st y-value
    int max = (int)series.Points.Select(x => x.YValues[0]).Max();
    // we delete any CLs we have
    ca.AxisY.CustomLabels.Clear();
    // now we add new custom labels
    for (int i = 0; i < max; i += interval)
    {
        CustomLabel cl = new CustomLabel();
        cl.FromPosition = i - interval / 2;
        cl.ToPosition = i + interval / 2;
        cl.Text = hhh_mm_ss(i);
        ca.AxisY.CustomLabels.Add(cl);
    }
}

The first parameters to call this are obvious; the last one however is tricky:

You need to decide to interval you want your labels to have. It will depend on various details of your chart:

  • the range of values
  • the size of the chart area
  • the size of the font of the axis

I didn't set any special Font in the function; CustomLabels use the same Font as normal axis labels, i.e. AxisY.LabelStyle.Font.

For my screenshot I prepared the chart like this:

ca.AxisX.Minimum = 0;
ca.AxisY.MajorTickMark.Interval = 60 * 60;  // one tick per hour
addCustomLabels(ca, s, 60 * 30);            // one label every 30 minutes

I have also added DataPoint Labels for testing to show the values..:

series.Points[p].Label = hhh_mm_ss((int)y) + "\n" + y;

Here is the result:

这篇关于在图表中将秒转换为hhh:mm:ss的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆