按照日期

问题描述:

分组创建多线图表系列从一个表我已经从查询动态表显示,由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://*.com/q/4791053/576719)。 –

+0

我并不是真的想要标签的系统时间,我的意思是记录在我的桌子上的时间。加上我需要使它成为一个新的系列,每次更改日期时, 但是如果我问错了问题,我很抱歉。 – waladi

你应该创建手动每个日期系列。所以你应该迭代你的数据集,每当你遇到新的日期时,你应该创建新的系列,将它添加到图表,并添加值。

如果您的数据集没有排序,您可能会使用临时词典(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 **和仿制药在那里是未知的 –