The first step in creating a new chart class is deciding what you want your chart to do and how you want it to appear. Once you have done that, you select the chart class that will best fulfill your needs. For this tutorial, we are going to make a graph chart, a chart with node (or shapes) with connections between the nodes. For our graph chart, we are going to define the following features:
• | Allow unlimited number of Nodes |
o | Nodes can be of different sizes and shapes |
o | Nodes can be labeled |
o | Nodes can be in any location |
• | Allow unlimited connections, or links, between nodes |
o | Links can have a direction, e.g., arrows |
o | Links can have a label |
o | Nodes can have one or more links |
From our requirements, it quickly becomes obvious that we should descend from a Shape chart (TRSShapeChart). This chart has the desirable qualities of allowing unlimited, arbitrarily sized and shaped, chart values. From there, all we will need to add are the connections, or links.
So our first step is to create a shape chart descendant.
The minimum step when creating a chart descendant is to create a chart value collection of the correct type. In our case, a collection called TRSGraphChartValues with TRSGraphChartValue collection items. To create our chart value types, we just need to override the CreateChartValues protected method. This function is called when the chart is created and should return an instance of your new chart values collection.
Next, you should expose your chart values collection. The TRSShapeChart already exposes the chart values using its Values property, but you should make your chart easier to use by reexposing the Values property with your new type.
The code below overrides the TRSShapeChart to create a TRSGraphChart, which will contain our graph values or nodes.
TRSGraphChart = class(TRSShapeChart)
private
{ Private declarations }
function GetValues: TRSGraphChartValues;
procedure SetValues(const Value: TRSGraphChartValues);
protected
{ Protected declarations }
function CreateChartValues: TRSChartValues; override;
public
{ Public declarations }
published
{ Published declarations }
property Values: TRSGraphChartValues read GetValues write SetValues stored IsValuesStored;
end; { TRSGraphChart }
{ TRSGraphChart }
function TRSGraphChart.CreateChartValues: TRSChartValues;
begin
result := TRSGraphChartValues.Create(Self, TRSGraphChartValue);
end;
function TRSGraphChart.GetValues: TRSGraphChartValues;
begin
result := TRSGraphChartValues(inherited Values);
end;
procedure TRSGraphChart.SetValues(const Value: TRSGraphChartValues);
begin
inherited Values := Value;
end;
Our next step is to Descend from TRSChartValue and TRSChartValues classes