I am having some trouble getting a TPointSeries to display properly when the other line series on a chart are showing Date values on the XAxis.
I am using the code below to add the line series values:
// populate the chart here too
int date = ds->getDate(i);
int year = date / 10000;
int month = (date - (year * 10000)) / 100;
int day = date - (year * 10000) - (month *100);
// set the date as the label separately so we will not display weekends (i.e. gaps)
int pos = lineSeries->AddXY(i, closes->getValue(i));
AnsiString dateLabel = DateToStr(EncodeDate((Word)year, (Word)month, (Word)day));
lineSeries->Labels->Labels[pos] = dateLabel;
This code is designed to stop weekends from disrupting my data - so the chart looks as if there are five days in a week, with no 'gaps' for weekends.
I then am trying to add corresponding points into a PointSeries using the combinations below:
int pos = pointSeries->AddXY(x, y); // where x counts up from zero
pointSeries->Labels->Labels[pos] = dateLabel;
dateLabel holds the results of DateToStr(EncodeDate(year,month,day) as done for the original line series.
This causes my new points to be added at the start of my series. I also tried replacing the first parameter to AddXY with the return from EncodeDate but that also does not work. I think I need to be able to work out for a given date, which point that corresponds to in the lineSeries ?
Or is there an easier way of doing this. I have the code working fine when I am displaying times on the XAxis, because there is no need to worry about weekends then and the lineSeries->AddXY() takes the encoded time as the first parameter and I can do the same for the AddXY() call for the point series in this case.
Thanks
Stew
Display a TPointSeries when X axis is showing Date values
Hi.
The above example demonstrates one way to do the no-weekends charting. Three basic steps:
1) generate an array of all valid dates
2) populate axis labels
3) populate series where point x value is mapped from valid dates array.
This won't work because your x values are 0,1,2,3,...first parameter to AddXY with the return from EncodeDate but that also does not work.
I think not. But I'd use slightly different approach. First, make an array of all non-weekend datetimes. Then generate bottom axis custom labels from this array -> end result is chart with correct (no weekends) labels. Now all you have to do is match point (real) datetime value with correct value in the array. Basically, use matched array index as x parameter in AddXY method call. Here is Delphi example. A similar approach can be used for BCB and even for TeeChart .NET (C#).Or is there an easier way of doing this.
Code: Select all
private
{ Private declarations }
ValidDates: Array [0..100] of TDate;
DateCount : Integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
// generate dates ... you can get this from sql, etc...
DateCount := 15;
ValidDates[0] := EncodeDate(2005,1,31);
ValidDates[1] := EncodeDate(2005,2,1);
ValidDates[2] := EncodeDate(2005,2,2);
ValidDates[3] := EncodeDate(2005,2,3);
ValidDates[4] := EncodeDate(2005,2,4);
ValidDates[5] := EncodeDate(2005,2,7);
ValidDates[6] := EncodeDate(2005,2,8);
ValidDates[7] := EncodeDate(2005,2,9);
ValidDates[8] := EncodeDate(2005,2,10);
ValidDates[9] := EncodeDate(2005,2,11);
ValidDates[10] := EncodeDate(2005,2,14);
ValidDates[11] := EncodeDate(2005,2,15);
ValidDates[12] := EncodeDate(2005,2,16);
ValidDates[13] := EncodeDate(2005,2,17);
ValidDates[14] := EncodeDate(2005,2,18);
// populate bottom axis with labels
// in this example user every 3rd label
Chart1.Axes.Bottom.Items.Clear;
for i := 0 to DateCount-1 do
if i mod 3 = 0 then
Chart1.Axes.Bottom.Items.Add(i,DateToStr(ValidDates[i]));
Chart1.Axes.Bottom.SetMinMax(0,DateCount-1);
end;
function FindMatch(value: TDate; pool: Array of TDate; Const lo_bound, hi_bound: Integer): Integer;
var i: Integer;
begin
Result := -1;
for i := lo_bound to hi_bound do
if value=pool[i] then
begin
Result := i;
break;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var xvals: Array[0..3] of TDate;
yvals: Array[0..3] of double;
i, xind: Integer;
begin
// this is only sample array (example)
xvals[0] := EncodeDate(2005,2,9);
yvals[0] := 5.2;
xvals[1] := EncodeDate(2005,2,10);
yvals[1] := 3.1;
xvals[2] := EncodeDate(2005,2,15);
yvals[2] := 2.5;
xvals[3] := EncodeDate(2005,2,16);
yvals[3] := 7;
// Add points to series
// Note that points have real date x values =>
// you have to map each value to internal index array
for i := 0 to 3 do
begin
xind := FindMatch(xvals[i],ValidDates,0,DateCount-1);
if xind <> -1 then Series1.AddXY(xind,yvals[i]);
end;
end;
1) generate an array of all valid dates
2) populate axis labels
3) populate series where point x value is mapped from valid dates array.
Marjan Slatinek,
http://www.steema.com
http://www.steema.com