2016-03-29 94 views
1

我有一個MsSql數據庫,它可以計算兩個日期之間的時間間隔(秒)。這工作正常。之後我在C#中使用此列,並將它們寫入數組中。在秒錶中將秒轉換爲hhh:mm:ss

此數組是稍後的圖表輸入。 到目前爲止,這工作得很好,但我無法找到一種方式來顯示像hhh:mm:ss這樣的格式的秒數,因爲時間跨度可能大於24h。

我試過ChartArea.AxisY.LabelStyle.Format =「hhmmss」;但它根本不起作用。

有沒有人有一個想法,我可以做到這一點?

編輯: 我補充這樣的數據:

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: 這裏就是我如何填充輸入數組

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應該看起來像這樣: enter image description here

在Excel格式顯示時大於24被稱爲 「並[h]:MM:SS; @」

EDIT4:

由於@TAW我幾乎設法解決我問題。我做了一些調整他的解決方案以及與此想出了:

在圖表代碼塊:

值「MAX」之前設定。

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; 
    } 

我的問題是現在,即使當代碼通過它運行沒有任何問題有時被示出沒有軸拉布勒(除了0:00)。

有沒有人和想法有什麼可能是錯的?

+0

你使用什麼樣的圖表? –

+0

Boxplot圖表 – FriendlyGuy

+0

什麼是UI框架?什麼是您使用的類型的全名? –

回答

0

你的任務涉及兩個部分:

  • 顯示秒的HHH:mm:ss格式
  • 把它們作爲在y軸標籤

在c#中沒有合適的date-time formatting string,所以我們不能使用內置的自動標籤及其格式。

不幸的是,也無法使用在自動標籤上調用函數的表達式。

所以我們不能使用這些。我們將不得不添加CustomLabels。這不是很難,但需要幾步。

但是讓我們從一個函數開始,將int轉換爲我們想要的hhh:mm:ss字符串;這應該做的工作:

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"); 
} 

也許它可以優化,但爲我們的目的,它會做的。我們需要創建CustomLabels。它們將取代正常的軸標籤,並且我們需要在每次綁定後將數據添加到數據的單獨循環中。

關於他們的一件特別的事情是他們的定位。這是我們需要給出的兩個值之間的差距,FromPositionToPosition,均以軸值爲單位。

另一個區別正常,自動標註的是,它是由我們來創造儘可能多或少數人由於工作需要需要..

該函數試圖創建一個數字將上升到最大Y - 值和空間的CustomLabels在給定的時間間隔:

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); 
    } 
} 

第一參數來調用此是顯而易見的;但最後一個是棘手的:

你需要決定你想要你的標籤有間隔。這將取決於你的星盤的各種細節:

  • 值的範圍
  • 圖表區域
  • 軸的字體

我沒有大小的尺寸在函數中設置任何特殊的Font; CustomLabels使用與正常軸標籤相同的Font,即AxisY.LabelStyle.Font

對於我的截圖我準備這樣的圖表:

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

我還添加數據點標籤進行測試,以顯示值..:

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

下面是結果:

enter image description here

+0

非常感謝,幫助了很多。對於最近的回覆,我感到很遺憾,我的大學週末很忙,我的大學工作很多...... 在大多數情況下,它的運作非常好,但隨着時代的波動,我不得不根據時代做一些調整30分鐘到400小時不等。 在主要文章中,我將寫我現在所做的,也許你看到我犯了一個錯誤:) – FriendlyGuy

0

如果你想顯示超過2個位數小時我想這應該

//yourTimeSpan is the TimeSpan that you already have 
var hoursDouble = Math.Floor(yourTimeSpan.TotalHours); 
string hours; 
string minutes; 
string seconds; 

//check hours 
if(hoursDouble < 10) 
{ 
    hours = string.Format("0{0}", hoursDouble); 
} 
else 
{ 
    hours = hoursDouble.ToString(); 
} 
//check minutes 
if (yourTimeSpan.Minutes < 10) 
{ 
    minutes = string.Format("0{0}", yourTimeSpan.Minutes); 
} 
else 
{ 
    minutes = yourTimeSpan.Minutes.ToString(); 
} 
//check seconds 
if (yourTimeSpan.Seconds < 10) 
{ 
    seconds = string.Format("0{0}", yourTimeSpan.Seconds); 
} 
else 
{ 
    seconds = yourTimeSpan.Seconds.ToString(); 
} 

string formattedSpan = String.Format("{0}:{1}:{2}", hours, minutes, seconds); 

你更新工作:我想這應該解決您的個位數

+0

嗯,如果我使用 string formattedSpan = String.Format(「{0}:{1:00}:{2:00}」,Convert.ToInt32 (yourTimeSpan.TotalHours),Convert.ToInt32(yourTimeSpan.Minutes)%60,Convert.ToInt32(yourTimeSpan.Seconds)%60); 它顯示了三位數的小時數,但我不知道如何在圖表中做到這一點。你能給我一個提示,我該怎麼做? – FriendlyGuy

+0

我更新了我的答案 –

+0

謝謝蒂姆,我編輯的解決方案也做同樣的事情。 我想我的主要問題是軸標籤的格式,因爲我不能在那裏使用時間跨度或有沒有辦法? – FriendlyGuy

0

被看到的問題

UPDATE:這個答案可能對其他讀者非常有用,但它幾乎錯過了OP的問題。我會離開它,因爲它的立場,但它不會在創建特殊格式的y軸標籤幫助..


大多數圖表問題源於無效或無用的x值幹。以下討論試圖幫助避免或繞過他們..

一個數字是一個數字,而您不能只是將其顯示爲DateTime,或者對於那個問題TimeSpan

因此,您需要將X-Values添加爲DateTimedouble,其中包含的值可以轉換爲DateTime。該fomer是我喜歡..

因此,而不是直接添加秒將其添加爲從給定DateTime偏移:

變化是這樣的

series.Points.AddXY(sec, yValues); 

要這樣:

var dt = new DateTime(0).AddSeconds(sec); 
series.Points.AddXY(dt, yValues); 

現在您可以根據需要使用日期和時間格式化字符串..:

chartArea.AxisX.LabelStyle.Format = "{mm:ss}"; 

你也可以將其添加爲doubles,實際上是從DateTimes通過ToOADate計算:

series.Points.AddXY(dt.ToOADate(), yValues); 

但現在你必須設置ChartValueType.DateTime大概也AxisX.IntervalTypeAxisX.Interval確保圖表變格式正確..:

s.XValueType = ChartValueType.DateTime; 
ca.AxisX.Interval = 5; 
ca.AxisX.IntervalType = DateTimeIntervalType.Seconds; 
ca.AxisX.LabelStyle.Format = "{mm:ss}"; 

選擇適合您的數據的值!

注意,與原有的代碼的問題是X-Values內部始終是doubles,但秒鐘都沒有在他們的整數值,但小數部分;所以你需要一些計算。這就是ToOADate所做的。下面是一個簡短的測試,顯示了1秒實際執行金額爲OADate double

enter image description here

最佳添加X-ValuesDateTimes因此所有進一步的處理可以依靠的類型..

更新我剛剛看到你最終添加了真正的代碼到你的問題,那就是使用Points.DataBindY。恐怕,這不會創造出有意義的X值。嘗試切換到Points.DataBindXY!當然,你綁定的X值也需要遵循我上面解釋的規則。

你可以在你的數組上做一個循環,並像上面顯示的那樣轉換數字;這裏是一個簡單的例子:

int[] seconds = new int[5] { 1, 3, 88, 123, 3333 }; 
    double[] oaSeconds = seconds.Select(x => new DateTime(0).AddSeconds(x).ToOADate()) 
           .ToArray(); 
+0

你好@TaW,非常感謝你的意見。我也想過把它轉換成日期時間,但這種方式我不知道如何顯示超過24小時的時間跨度。你也許也知道我該怎麼做?在此先感謝 – FriendlyGuy

+0

你的意思是說,23小時過去了,而不是繼續到今天?不,我認爲這沒有時間格式。這個imo相當於一個自定義字符串,我認爲你必須將這些字符串放到CustomLabels中。這些有點棘手的地方..或者你可以嘗試設置'AxisLabel'每個數據點,調用你寫的函數。您必須嘗試使用​​Interval來顯示適當數量的這些標籤。 – TaW

+0

說實話,我不是一個專業的程序員,我只是在我的空閒時間這樣做,並在大學中使用它來處理數據。由於boxplot圖正在計算它自己所需的值,所以我不認爲我可以手動設置AxisLabels,因此我可能需要一個自定義字符串。你能不能給我一個提示,我該怎麼做?它會幫助我很多,因爲我不知道如何自定義字符串:) – FriendlyGuy