Two solutions
(1)
Each chart source can house several x and y values per data point. While in case of a LineSeries the additional y values are reserved for additional data levels (such as in a stacked bar series) the additional x values are freely available. So you could stuff additional data point information into the extra x value. Unfortunately there is no direct series method to add an additional x value by a variant of the Add* methods, but you could call the method AddXListYList of the internal listsource to which the AddXY values are stored anyway.
procedure TForm1.PrepareDataForSolution1;
var
i: Integer;
x, y: Double;
symbol: TSeriesPointerStyle;
clr: TColor;
begin
Chart1LineSeries1.ListSource.XCount := 2; // prepare for two x values!
for i := 0 to DATA_COUNT do begin
x := i;
y := Random;
symbol := TSeriesPointerStyle(Random(ord(High(TSeriesPointerStyle)) + 1)); // random pointer style
clr := RGBToColor(Random(256), Random(256), Random(256));
Chart1LineSeries1.ListSource.AddXListYList(
[x, ord(symbol)], // two x values
[y], // one y value
'', clr); // label and color
end;
end;
(2)
A less "hacky" solution, in my eyes, would be to define your own data type which directly contains the additional data values:
type
TData = record
x, y: Double; // x, y values
Symbol: TPointerStyle; // the pointer style used for this data point
Color: TColor; // the color of this data point
end;
TDataArray = array of TData;
var
data: TDataArray;
procedure TForm1.PrepareDataForSolution2;
var
i: Integer;
begin
Setlength(data, DATA_COUNT);
for i := 0 to DATA_COUNT-1 do begin
data[i].x := i;
data[i].y := Random;
data[i].Symbol := TSeriesPointerStyle(Random(ord(High(TSeriesPointerStyle)) + 1)); // random pointer style
data[i].Color := RGBToColor(Random(256), Random(256), Random(256));
end;
UserDefinedChartSource1.PointsNumber := DATA_COUNT;
end;
procedure TForm1.UserDefinedChartSource1GetChartDataItem(
ASource: TUserDefinedChartSource; AIndex: Integer; var AItem: TChartDataItem);
begin
AItem.X := data[AIndex].x;
AItem.Y := data[AIndex].y;
AItem.Color := data[AIndex].Color;
end;
Declare a variable "data" of type TDataArray and populate it with your data; add also the Symbol and Color elements needed.
In order to pass these data to the series add a TUserDefinedChartSource to the chart and link it to the "Source" property of the series. Once the data array is populated you must set the PointsNumber of the UserDefinedChartSource to the Length of the array. This tells the chartsource how many data points will be passed. Then write an event handler for TUserDefinedChartSeries.OnGetChartDataItem and define how the array data are assigned to the chart data items.
Find a demo showing both approaches in the attachment.