YOUSEFUL / DELPHI / COMPONENTS
TAtlasPolarPlot
Radar (spider) chart: categories as spokes, each series a filled or outlined shape across them.
Description
A radar chart. Categories are the spokes, starting at StartAngle degrees from twelve o'clock and following Clockwise. Each series holds one value per category and is drawn as a closed outline two pixels wide with a dot at every vertex, filled when Style is psFilled. The radial scale is a TAtlasPlotAxis (RadialAxis) with zero at the centre unless the data goes below zero. Rings are polygons or circles (GridStyle).
NaN leaves a gap: the outline joins only neighbouring values (including the step from the last spoke back to the first) and the series is not filled. The drawing surface has no transparency, so fills are opaque; every fill is painted first, then the grid, then all outlines, which keeps overlapping series readable.
Set the categories before adding series; at least three are needed. Changing their number discards every series. Invalid series raise EAtlasPlotError and add nothing. Pixel queries describe the most recent render.
This is a category chart: true angle/radius polar series, wind roses and an FMX version are not implemented.
Members
| Member | Kind | What it does |
|---|---|---|
Create | constructor | Creates an empty radar chart, 480 x 320 pixels: filled style, polygon grid, legend shown, first spoke at twelve o'clock, spokes clockwise, automatic RadialAxis. |
Destroy | destructor | Frees the categories, series and radial axis. |
AddSeries | method | Adds a series with one value per category, in category order, and returns its index. |
ClearSeries | method | Removes every series; the categories stay. |
SeriesName | method | The name given to AddSeries. |
SeriesValue | method | The value of one series on one spoke; NaN for a gap. |
HitTest | method | Finds the nearest drawn vertex within 8 pixels of (X, Y) in the most recent render. |
ValueToPixel | method | Where Value would sit on the spoke of Category in the most recent render; values beyond the radial range are placed on the centre or the rim. |
SeriesCount | property | Number of series. |
Centre | property | Centre of the radar in the most recent render; (0, 0) before one. |
Radius | property | Radius of the outer ring in pixels in the most recent render; 0 before one or when the area was too small to draw. |
Categories | property | The spokes, one line each, in drawing order. |
RadialAxis | property | The TAtlasPlotAxis from the centre to the rim. |
Style | property | psFilled paints each complete series as a shape blended 70 % towards the background, below the grid and every outline; a series with a gap is never filled. |
GridStyle | property | Rings as polygons through the spokes (pgPolygons) or as circles (pgCircles). |
ShowLegend | property | Draws a vertical legend with one swatch per series at the right; it takes at most two fifths of the width. |
StartAngle | property | Angle in degrees from twelve o'clock to the first spoke, measured clockwise. |
Clockwise | property | Whether later categories follow clockwise (True) or anticlockwise. |
BeginUpdate | method from TAtlasCustomChart | Starts a batch of changes: until the matching EndUpdate, property changes and added data do not repaint the control. |
EndUpdate | method from TAtlasCustomChart | Ends a batch started by BeginUpdate. |
Render | method from TAtlasCustomChart | Draws the chart into any TAtlasPlotSurface (for example a TAtlasSvgSurface or a TAtlasCanvasSurface over your own canvas), filling Bounds. |
RenderTo | method from TAtlasCustomChart | Draws the chart onto a VCL canvas, for example a printer canvas or a bitmap you own, filling Bounds. |
CreateBitmap | method from TAtlasCustomChart | Returns a new 24-bit bitmap of the given size with the chart drawn on it; the caller frees it. |
ToSVG | method from TAtlasCustomChart | Returns the chart as an SVG document of the given size (1 to 16384 pixels). |
SaveToFile | method from TAtlasCustomChart | Writes the chart to .png, .bmp, .emf or .svg, chosen by the extension (case does not matter); any other extension raises EAtlasPlotError before anything is written. |
PaletteColor | method from TAtlasCustomChart | One of ten built-in series colours (blue, orange, green, red, purple, olive, dark blue, teal, salmon, grey). |
Title | property from TAtlasCustomChart | Bold caption centred at the top. |
Footnote | property from TAtlasCustomChart | Caption centred at the bottom. |
Color | property from TAtlasCustomChart | Background colour, clWhite by default. |
Font | property from TAtlasCustomChart | Font of every caption; the title uses it in bold. |
OnMouseMove | event from TAtlasCustomChart | The standard VCL mouse event, published by the base class. |
Constructors
Create constructor
constructor Create(AOwner: TComponent); override;Creates an empty radar chart, 480 x 320 pixels: filled style, polygon grid, legend shown, first spoke at twelve o'clock, spokes clockwise, automatic RadialAxis.
Destructors
Destroy destructor
destructor Destroy; override;Frees the categories, series and radial axis.
Properties
SeriesCount property
property SeriesCount: Integer read GetSeriesCount;Number of series.
Centre property
property Centre: TPoint read FCentre;Centre of the radar in the most recent render; (0, 0) before one.
Radius property
property Radius: Integer read FRadius;Radius of the outer ring in pixels in the most recent render; 0 before one or when the area was too small to draw.
Categories property
property Categories: TStrings read GetCategories write SetCategories;The spokes, one line each, in drawing order. Set them before adding series. Changing the number of categories discards every series (they were sized for the old spokes); renaming them keeps the series. With fewer than three the chart shows "At least three categories are needed".
Polar.Categories.CommaText := 'Speed,Reliability,Price,Support,"Ease of use"';RadialAxis property
property RadialAxis: TAtlasPlotAxis read FRadialAxis write SetRadialAxis;The TAtlasPlotAxis from the centre to the rim. Automatic by default: from 0 (or the lowest value when it is negative) to the highest value, rounded to whole ticks. RadialAxis.SetRange(0, 10) fixes it. Tick captions are drawn along the first spoke in grey; LabelFormat formats them. Assigning copies another axis's settings.
Polar.RadialAxis.SetRange(0, 10);Style property
property Style: TAtlasPolarStyle read FStyle write SetStyle default psFilled;psFilled paints each complete series as a shape blended 70 % towards the background, below the grid and every outline; a series with a gap is never filled. psOutline draws outlines only. See TAtlasPolarStyle.
GridStyle property
property GridStyle: TAtlasPolarGrid read FGridStyle write SetGridStyle default pgPolygons;Rings as polygons through the spokes (pgPolygons) or as circles (pgCircles). See TAtlasPolarGrid.
ShowLegend property
property ShowLegend: Boolean read FShowLegend write SetShowLegend default True;Draws a vertical legend with one swatch per series at the right; it takes at most two fifths of the width.
StartAngle property
property StartAngle: Integer read FStartAngle write SetStartAngle default 0;Angle in degrees from twelve o'clock to the first spoke, measured clockwise. Values are normalised to 0..359, so -90 becomes 270.
Clockwise property
property Clockwise: Boolean read FClockwise write SetClockwise default True;Whether later categories follow clockwise (True) or anticlockwise.
Title propertyinherited from TAtlasCustomChart
property Title: string read FTitle write SetTitle;Bold caption centred at the top. Empty (the default) leaves no room for it.
Footnote propertyinherited from TAtlasCustomChart
property Footnote: string read FFootnote write SetFootnote;Caption centred at the bottom. Empty (the default) leaves no room for it.
Color propertyinherited from TAtlasCustomChart
property Color default clWhite;Background colour, clWhite by default. Chart parts are blended towards it (box fills, radar fills), and heat map cells are outlined with it.
Font propertyinherited from TAtlasCustomChart
property Font;Font of every caption; the title uses it in bold. The height of Ag in this font (at least 8 pixels) sets the chart's margins, label spacing and marker sizes. Changing it repaints the control.
Events
OnMouseMove eventinherited from TAtlasCustomChart
property OnMouseMove;The standard VCL mouse event, published by the base class. Pass X and Y to HitTest to find what is under the pointer.
Methods
AddSeries method
function AddSeries(const Name: string; const Values: TArray<Double>; Color: TColor = clDefault): Integer;Adds a series with one value per category, in category order, and returns its index. NaN leaves a gap. At least three categories must be set first, and Length(Values) must equal the category count. Infinite values, magnitudes above 1E100 and, on a logarithmic RadialAxis, values of 0 or less raise EAtlasPlotError and add nothing. The values are copied. Color clDefault uses PaletteColor(Index); an empty Name shows as Series n in the legend.
Polar.Categories.CommaText := 'Speed,Price,Support';
Index := Polar.AddSeries('Ours', [7, 6, 9]);ClearSeries method
procedure ClearSeries;Removes every series; the categories stay.
SeriesName method
function SeriesName(Index: Integer): string;The name given to AddSeries. An index outside 0..SeriesCount - 1 raises the list's range error.
SeriesValue method
function SeriesValue(Series, Category: Integer): Double;The value of one series on one spoke; NaN for a gap.
HitTest method
function HitTest(X, Y: Integer; out Series, Category: Integer): Boolean;Finds the nearest drawn vertex within 8 pixels of (X, Y) in the most recent render. On a tie the series drawn last (on top) wins. Returns False with both set to -1 when no vertex is close; gaps have no vertex.
if Polar.HitTest(X, Y, SeriesIndex, CategoryIndex) then
Text := Format('%s, %s: %.1f', [Polar.SeriesName(SeriesIndex), Polar.Categories[CategoryIndex],
Polar.SeriesValue(SeriesIndex, CategoryIndex)]);ValueToPixel method
function ValueToPixel(Category: Integer; const Value: Double; out Pixel: TPoint): Boolean;Where Value would sit on the spoke of Category in the most recent render; values beyond the radial range are placed on the centre or the rim. Returns False (and Pixel (0, 0)) before a render, for an unknown category, or for a value a logarithmic axis cannot show.
BeginUpdate methodinherited from TAtlasCustomChart
procedure BeginUpdate;Starts a batch of changes: until the matching EndUpdate, property changes and added data do not repaint the control. Calls nest.
Polar.BeginUpdate;
try
Polar.Title := 'Updated';
Polar.Footnote := 'Source: monitoring';
finally
Polar.EndUpdate;
end;EndUpdate methodinherited from TAtlasCustomChart
procedure EndUpdate;Ends a batch started by BeginUpdate. When the outermost batch ends the control is invalidated once. A call without a matching BeginUpdate is ignored.
Render methodinherited from TAtlasCustomChart
procedure Render(ASurface: TAtlasPlotSurface; const Bounds: TRect);Draws the chart into any TAtlasPlotSurface (for example a TAtlasSvgSurface or a TAtlasCanvasSurface over your own canvas), filling Bounds. Raises EAtlasPlotError when ASurface is nil. Pixel queries such as HitTest then describe this render; unlike the other output methods, Render does not restore the on-screen layout afterwards.
Svg := TAtlasSvgSurface.Create(600, 400);
try
Polar.Render(Svg, Rect(0, 0, 600, 400));
Text := Svg.Document;
finally
Svg.Free;
end;RenderTo methodinherited from TAtlasCustomChart
procedure RenderTo(Target: TCanvas; const Bounds: TRect);Draws the chart onto a VCL canvas, for example a printer canvas or a bitmap you own, filling Bounds. When the control has a window handle it then re-runs its on-screen layout, so hit tests keep matching the screen.
Polar.RenderTo(Bitmap.Canvas, Rect(0, 0, Bitmap.Width, Bitmap.Height));CreateBitmap methodinherited from TAtlasCustomChart
function CreateBitmap(AWidth, AHeight: Integer): Vcl.Graphics.TBitmap;Returns a new 24-bit bitmap of the given size with the chart drawn on it; the caller frees it. Both sizes must be 1 to 16384 pixels, otherwise EAtlasPlotError is raised. Works without a window, for example in a console program or a service.
Bitmap := Polar.CreateBitmap(800, 500);
try
Bitmap.SaveToFile('chart.bmp');
finally
Bitmap.Free;
end;ToSVG methodinherited from TAtlasCustomChart
function ToSVG(AWidth, AHeight: Integer): string;Returns the chart as an SVG document of the given size (1 to 16384 pixels). Text is XML-escaped. Works without a window.
Text := Polar.ToSVG(640, 420);SaveToFile methodinherited from TAtlasCustomChart
procedure SaveToFile(const FileName: string; AWidth: Integer = 0; AHeight: Integer = 0);Writes the chart to .png, .bmp, .emf or .svg, chosen by the extension (case does not matter); any other extension raises EAtlasPlotError before anything is written. A size of 0 or less uses the control's Width and Height; sizes above 16384 raise. The image is written to FileName.part and then renamed over the target, so a failed export keeps an existing file. Works without a window.
Polar.SaveToFile('chart.png', 800, 500);
Polar.SaveToFile('chart.svg'); // the control's own sizePaletteColor methodinherited from TAtlasCustomChart
class function PaletteColor(Index: Integer): TColor; static;One of ten built-in series colours (blue, orange, green, red, purple, olive, dark blue, teal, salmon, grey). The index wraps: PaletteColor(10) equals PaletteColor(0), and negative indexes use their absolute value. Categories and series with colour clDefault take PaletteColor of their index.
Polar.Color := TAtlasCustomChart.PaletteColor(3);Examples
Compare two releases on six criteria
A fixed 0..10 scale, a legend, and a gap for a score that is not known yet.
uses
System.Math, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Atlas.PolarPlot;
function AddComparison(Form: TForm): TAtlasPolarPlot;
begin
Result := TAtlasPolarPlot.Create(Form);
Result.Parent := Form;
Result.Align := alClient;
Result.Title := 'Release comparison';
Result.RadialAxis.SetRange(0, 10);
Result.Categories.CommaText := 'Speed,Reliability,Price,Support,"Ease of use",Features'; // first
Result.AddSeries('Release 4', [7, 8.5, 6, 5, 7.5, 8]);
Result.AddSeries('Release 5', [8.5, 9, 6.5, NaN, 8, 9], clMaroon); // NaN: drawn as a gap, not filled
Result.GridStyle := pgCircles;
end;Related
TAtlasPolarStyle · TAtlasPolarGrid · TAtlasCustomChart · TAtlasPlotAxis