2014-02-19 101 views
0

分組創建多線圖表系列從一個表我已經從查詢動態表顯示,由DBGrid的,看上去像這樣按照日期

code | Name | Date  | Time |Score 
1 | Alex | 01-Feb-14 | 0600 |5 
1 | Alex | 01-Feb-14 | 0700 |7 
1 | Alex | 01-Feb-14 | 0800 |8 
1 | Alex | 02-Feb-14 | 0600 |7 
1 | Alex | 02-Feb-14 | 0800 |8 
1 | Alex | 02-Feb-14 | 0900 |8 
1 | Alex | 03-Feb-14 | 0700 |7 
1 | Alex | 03-Feb-14 | 0800 |5 
1 | Alex | 03-Feb-14 | 0900 |8 

的輸入,查詢是code=1, date1=01-feb-14, date2=03-feb-14

我怎樣才能製作具有多個系列的折線圖,按xlabel = time和y value = score按日期分組? 我的僞代碼爲:

for date1 to date 2 
chart1.addseries 
    for time=lowesttime to highesttime do 
    begin 
    series.xlabel = time 
    series.yvalue = score 
    end 

它會是這個樣子 chart sample

+0

thx Sir Rufo先生的照片,無論如何,這是我的第一個問題,如果我需要提供更多的數據或其他請告訴我。 謝謝 – waladi

+0

可能的重複,[用時間繪製TChart作爲X軸](http://stackoverflow.com/q/4791053/576719)。 –

+0

我並不是真的想要標籤的系統時間,我的意思是記錄在我的桌子上的時間。加上我需要使它成爲一個新的系列,每次更改日期時, 但是如果我問錯了問題,我很抱歉。 – waladi

回答

1

你應該創建手動每個日期系列。所以你應該迭代你的數據集,每當你遇到新的日期時,你應該創建新的系列,將它添加到圖表,並添加值。

如果您的數據集沒有排序,您可能會使用臨時詞典(TDcitionary<integer, TLineSeries>Generics.Collections)來存儲系列參考。

DateTime值實際上是一個double其中int部分表示日期。所以你有每個日期的自己的關鍵。您也可以將它分配到系列Tag屬性以供進一步使用。

在填充系列值之前和之後使用BeginUpdate()EndUpdate()方法。 創建系列時,請使用圖表引用作爲所有者。下一次你清除圖表中的所有系列時,它們將被完全銷燬。

下面是一個例子代碼:

procedure TForm7.UpdateSeries(); 
var sd : TDictionary<integer, TLineSeries>; 
    s : TLineSeries; 
    d : TDate; 
    dInt : integer; 
    x : double; 
    xlabel : string; 
    i : integer; 
begin 
    DataChart.SeriesList.Clear(); 

    sd := TDictionary<integer, TLineSeries>.Create(); 
    try 
     while not query.eof do begin 
      d := query.FieldByName('Date').AsDateTime; 
      dInt := round(d); 

      if not sd.ContainsKey(dInt) then begin 
       s := TLineSeries.Create(DataChart); 
       s.Tag := dInt; {for further use} 
       DataChart.AddSeries(s); 
       s.ParentChart := DataChart; 
       s.Title := DateToStr(query.FieldByName('date').AsDateTime); 
       s.Color := Random($FFFFFF); 

       s.BeginUpdate(); 

       sd.AddOrSetValue(dInt, s); 
      end 
      else s := sd[dInt]; 

      //x value and label 
      x := query.FieldByName('time').AsDateTime; 
      xlabel := Format('Label %f', [x]); 

      s.AddXY(x, query.FieldByName('score').AsInteger, xlabel); 

      query.Next(); 
     end; 
    finally 
     for i := 0 to DataChart.SeriesCount - 1 do begin 
      DataChart.Series[i].EndUpdate(); 
     end; 

     sd.Free(); 
    end; 
end; 

的問題針對Delphi-7,它不知道generics。所以在這種情況下,最簡單的方法是按日期排序數據集(ORDER BY date)。然後每次遇到新的約會,你都應該創造新的系列。首先,您需要初始化dInt := 0,然後將其與FieldByName('date')進行比較。如果它改變了,你應該創建新的系列。

dInt := 0; 
    try 
     while not query.eof do begin 
      d := query.FieldByName('Date').AsDateTime; 
      if round(d) <> dInt then begin 
       dInt := round(d); 
       s := TLineSeries.Create(DataChart); 
       .... 
+0

如果列表已經按組密鑰第一個'ORDER BY Date,Time'排序,則不需要字典。需要一個新的系列,如果組密鑰更改 –

+0

@SirRufo是的,這就是爲什麼我寫了「如果你的數據集沒有排序」 – teran

+0

哦,我只是專注於代碼......但問題目標** Delphi7 **和仿製藥在那裏是未知的 –