YOUSEFUL / DELPHI / COMPONENTS

TAtlasPolarPlot

Radar (spider) chart: categories as spokes, each series a filled or outlined shape across them.

Visual control Palette: Atlas Plot Unit Atlas.PolarPlot · Inherits TAtlasCustomChart · Product Atlas Plot Pro

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

MemberKindWhat it does
CreateconstructorCreates an empty radar chart, 480 x 320 pixels: filled style, polygon grid, legend shown, first spoke at twelve o'clock, spokes clockwise, automatic RadialAxis.
DestroydestructorFrees the categories, series and radial axis.
AddSeriesmethodAdds a series with one value per category, in category order, and returns its index.
ClearSeriesmethodRemoves every series; the categories stay.
SeriesNamemethodThe name given to AddSeries.
SeriesValuemethodThe value of one series on one spoke; NaN for a gap.
HitTestmethodFinds the nearest drawn vertex within 8 pixels of (X, Y) in the most recent render.
ValueToPixelmethodWhere 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.
SeriesCountpropertyNumber of series.
CentrepropertyCentre of the radar in the most recent render; (0, 0) before one.
RadiuspropertyRadius of the outer ring in pixels in the most recent render; 0 before one or when the area was too small to draw.
CategoriespropertyThe spokes, one line each, in drawing order.
RadialAxispropertyThe TAtlasPlotAxis from the centre to the rim.
StylepropertypsFilled 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.
GridStylepropertyRings as polygons through the spokes (pgPolygons) or as circles (pgCircles).
ShowLegendpropertyDraws a vertical legend with one swatch per series at the right; it takes at most two fifths of the width.
StartAnglepropertyAngle in degrees from twelve o'clock to the first spoke, measured clockwise.
ClockwisepropertyWhether later categories follow clockwise (True) or anticlockwise.
BeginUpdatemethod from TAtlasCustomChartStarts a batch of changes: until the matching EndUpdate, property changes and added data do not repaint the control.
EndUpdatemethod from TAtlasCustomChartEnds a batch started by BeginUpdate.
Rendermethod from TAtlasCustomChartDraws the chart into any TAtlasPlotSurface (for example a TAtlasSvgSurface or a TAtlasCanvasSurface over your own canvas), filling Bounds.
RenderTomethod from TAtlasCustomChartDraws the chart onto a VCL canvas, for example a printer canvas or a bitmap you own, filling Bounds.
CreateBitmapmethod from TAtlasCustomChartReturns a new 24-bit bitmap of the given size with the chart drawn on it; the caller frees it.
ToSVGmethod from TAtlasCustomChartReturns the chart as an SVG document of the given size (1 to 16384 pixels).
SaveToFilemethod from TAtlasCustomChartWrites 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.
PaletteColormethod from TAtlasCustomChartOne of ten built-in series colours (blue, orange, green, red, purple, olive, dark blue, teal, salmon, grey).
Titleproperty from TAtlasCustomChartBold caption centred at the top.
Footnoteproperty from TAtlasCustomChartCaption centred at the bottom.
Colorproperty from TAtlasCustomChartBackground colour, clWhite by default.
Fontproperty from TAtlasCustomChartFont of every caption; the title uses it in bold.
OnMouseMoveevent from TAtlasCustomChartThe 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".

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
Polar.SaveToFile('chart.png', 800, 500);
Polar.SaveToFile('chart.svg');   // the control's own size

PaletteColor 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.

pascal
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.

pascal
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;

TAtlasPolarStyle · TAtlasPolarGrid · TAtlasCustomChart · TAtlasPlotAxis

Also in Atlas Plot Pro

TAtlasBoxPlot · TAtlasHeatMap