YOUSEFUL / DELPHI / COMPONENTS
TAtlasPlot
VCL chart control with line, step, area, bar, point and pie series, zoom, hit testing and PNG, SVG, EMF and CSV export.
Description
The one component of Atlas Plot (palette page Atlas Plot). A chart holds a collection of series (TAtlasPlotSeries) drawn against two axes, ArgumentAxis and ValueAxis (TAtlasPlotAxis), with a title, a footnote and a legend.
- Form. The first visible series decides it: if that series is a pie, the chart is a pie (or donut) of that series and nothing else is drawn; otherwise pie series are ignored.
- Layout. Every output (screen, bitmap, metafile, printer, SVG) goes through
Render, so they all look the same. Sizes derive from theFontline height. - Interaction. Left-drag zooms, right-drag pans, the wheel zooms about the cursor, a double-click resets;
OnPointClickreports the clicked point.HitTest,ValuesToPixelandPixelToValuesdescribe the most recent render; exports at another size do not disturb the on-screen mapping of a chart with a window. For an off-screen chart the most recent render is the latest export, so its pixels can be hit-tested. - Validation. Values must be finite and within 1E100; pie slices cannot be negative. Invalid input raises EAtlasPlotError and leaves the chart unchanged. Logarithmic axes skip non-positive points.
- Persistence. Series and their points are stored in the form file.
DataToCSV/DataFromCSVexchange data.
Wrap bulk changes in BeginUpdate / EndUpdate; every point added otherwise invalidates the chart and notifies its listeners. The control is a VCL control with no locking: create and change it on the main thread. A chart without a parent (TAtlasPlot.Create(nil)) renders and exports in a console program, as the PlotToPng sample shows.
Not implemented: data-aware series bound to a TDataSet, secondary axes, multiple panes, 3D, gradients, animation, further series kinds (bubble, candle, gauge, polar), a print dialog or preview, keyboard navigation, and FMX or non-Windows platforms. The control runs on VCL for Win32 and Win64.
Members
| Member | Kind | What it does |
|---|---|---|
Create | constructor | Creates an empty chart: no series, white background (Color = clWhite), 480 x 320 pixels, legend on the right, zoom and pan allowed, double buffered. |
Destroy | destructor | Frees the series, both axes and the change-listener list. |
BeginUpdate | method | Starts a batch. |
EndUpdate | method | Closes a batch. |
AddChangeListener | method | Registers a method that is called, with the chart as Sender, after any change to series, points, axes, titles, legend, rotation, stacking, donut size or zoom; once per BeginUpdate / EndUpdate batch. |
RemoveChangeListener | method | Unregisters a listener added with AddChangeListener. |
AddSeries | method | Appends a new series to Series and returns it. |
Clear | method | Removes every series and ends any zoom. |
SeriesColor | method | The colour series Index is drawn in: its own Color, or when that is clDefault, entry Index mod 10 of a fixed ten-colour palette that starts blue, orange, green, red. |
AddTrendLine | method | Adds a straight least-squares line fitted to the values of Source and returns it: a pkLine series titled Source.Title + ' trend' with two points, at the smallest and largest argument of Source. |
AddMovingAverage | method | Adds a trailing simple moving average of Source and returns it: a pkLine series titled Format('%s avg(%d)', [Title, Period]). |
Render | method | Draws the whole chart (background, title, footnote, legend, axes, series and marks) onto any drawing surface inside Bounds. |
RenderTo | method | Draws the chart onto any VCL canvas inside Bounds: a bitmap, a metafile canvas, Printer.Canvas, or the canvas of another control. |
ZoomTo | method | Shows exactly the given window, in data units, on both axes (no rounding to whole steps), sets Zoomed, repaints and fires OnZoom. |
ResetZoom | method | Ends the zoom, returning to the automatic or manual axis ranges, repaints and fires OnZoom. |
PanBy | method | Moves the visible window as if the content were dragged by DeltaX, DeltaY pixels: a positive DeltaX reveals lower arguments, a positive DeltaY moves the content down. |
ZoomAround | method | Scales the visible window by Factor about the pixel X, Y, keeping the data value under that pixel in place: 0.5 halves the window, 2 doubles it. |
HitTest | method | Reports which point is drawn at pixel X, Y of the most recent render. |
ValuesToPixel | method | Converts data values to a pixel of the most recent render, honouring logarithmic, inverted and rotated axes. |
PixelToValues | method | Converts a pixel of the most recent render back to data values (Arg on the argument axis, Val on the value axis); the inverse of ValuesToPixel. |
CreateBitmap | method | Renders the chart into a new 24-bit bitmap of the given size and returns it; the caller frees it. |
ToSVG | method | Renders the chart as an SVG document of the given size and returns the text (declared UTF-8). |
SaveToFile | method | Writes the chart to a file whose extension selects the format: .png, .bmp, .emf (enhanced metafile) and .svg render the chart at AWidth x AHeight pixels (0 means the control's current Width or Height); .csv writes DataToCSV as UTF-8 without BOM and ignores the size. |
CopyToClipboard | method | Places a bitmap of the chart, at the control's current size, on the clipboard. |
DataToCSV | method | Returns every point as CSV text with CRLF line ends. |
DataFromCSV | method | Replaces every series with the data in Text, in the format DataToCSV writes. |
Zoomed | property | True while a zoom window set by ZoomTo, the mouse, the wheel or PanBy is in effect. |
PlotRect | property | The rectangle, in pixels of the most recent render, that holds the series (inside the axes). |
Series | property | The series collection, drawn in order (later series on top). |
ArgumentAxis | property | The axis of the point arguments (X): horizontal, or vertical when Rotated is True. |
ValueAxis | property | The axis of the point values (Y): vertical, or horizontal when Rotated is True. |
Title | property | Bold heading centred above the chart; empty means no heading and no space reserved. |
Footnote | property | Line of text centred at the bottom of the chart; empty means none. |
LegendVisible | property | Shows the legend. |
LegendPosition | property | Side of the chart the legend occupies. |
Rotated | property | Swaps the axes: the argument axis runs vertically (bottom to top) and the value axis horizontally, which turns bars into horizontal bars and draws lines sideways. |
Stacking | property | Stacks bars on bars and areas on areas; lines, steps and points never stack. |
DonutPercent | property | Size of the hole in a pie chart, as a percentage of the radius: 0 draws a full pie, 45 a typical donut. |
AllowZoom | property | Enables mouse zooming: drag a rectangle with the left button (more than 4 pixels each way), turn the wheel over the plot, double-click to reset. |
AllowPan | property | Enables panning by dragging with the right button inside the plot. |
OnPointClick | event | Fires when the left button is released over a bar, vertex, point or slice (as HitTest sees it) and the press did not become a zoom drag. |
OnZoom | event | Fires after every change of the zoom window: ZoomTo, a mouse zoom, each step of a pan, a wheel step, and ResetZoom when the chart was zoomed. |
Align | property | Standard VCL alignment, published. |
Anchors | property | Standard VCL anchors, published. |
Color | property | Background of the whole chart and the plot area. |
Constraints | property | Standard VCL size constraints, published. |
Enabled | property | Standard VCL property; a disabled chart still paints but receives no mouse input. |
Font | property | Font of every text. |
ParentFont | property | Standard VCL property: take the parent's font. |
ParentShowHint | property | Standard VCL property, published. |
PopupMenu | property | Standard VCL popup menu. |
ShowHint | property | Standard VCL hint display. |
TabOrder | property | Standard VCL tab order. |
TabStop | property | When True, clicking the chart gives it the focus, which also makes it the target of wheel messages. |
Visible | property | Standard VCL visibility. |
OnClick | event | Standard VCL click: fires when the left button is released inside the control, before OnPointClick, also at the end of a zoom drag. |
OnDblClick | event | Standard VCL double click. |
OnMouseDown | event | Standard VCL mouse event; the chart's own zoom and pan handling runs as well. |
OnMouseMove | event | Standard VCL mouse event. |
OnMouseUp | event | Standard VCL mouse event; fires before OnPointClick. |
OnResize | event | Standard VCL resize event. |
Constructors
Create constructor
constructor Create(AOwner: TComponent); override;Creates an empty chart: no series, white background (Color = clWhite), 480 x 320 pixels, legend on the right, zoom and pan allowed, double buffered. Pass nil as owner for an off-screen chart that you free yourself; such a chart can still render, export and hit-test.
Plot := TAtlasPlot.Create(nil);
try
Plot.AddSeries('Load').AddY(3);
Plot.SaveToFile('load.png', 640, 400);
finally
Plot.Free;
end;Destructors
Destroy destructor
destructor Destroy; override;Frees the series, both axes and the change-listener list. Listeners are not notified during destruction.
Properties
Zoomed property
property Zoomed: Boolean read FZoomed;True while a zoom window set by ZoomTo, the mouse, the wheel or PanBy is in effect. ResetZoom, Clear, DataFromCSV and changing Stacking end it.
PlotRect property
property PlotRect: TRect read FPlot;The rectangle, in pixels of the most recent render, that holds the series (inside the axes). Empty when that render drew no cartesian plot, for example a pie.
Plot.ZoomAround(Plot.PlotRect.CenterPoint.X, Plot.PlotRect.CenterPoint.Y, 0.5);Series property
property Series: TAtlasPlotSeriesList read FSeries write SetSeries;The series collection, drawn in order (later series on top). Editable in the Object Inspector; points persist in the form file. Assigning another list copies its series. See TAtlasPlotSeriesList.
Plot.Series.Find('Revenue').Visible := False;ArgumentAxis property
property ArgumentAxis: TAtlasPlotAxis read FArgumentAxis write SetArgumentAxis;The axis of the point arguments (X): horizontal, or vertical when Rotated is True. Automatic ranges keep the exact data span (plus half a bar slot on each side when there are bars). When the first visible series has point texts and the axis is neither date/time nor logarithmic, those texts replace the numeric ticks. Assigning another axis copies its settings.
Plot.ArgumentAxis.DateTime := True;ValueAxis property
property ValueAxis: TAtlasPlotAxis read FValueAxis write SetValueAxis;The axis of the point values (Y): vertical, or horizontal when Rotated is True. Automatic ranges are rounded outward to whole tick steps (to whole decades when logarithmic). A zero line is drawn when zero lies inside the range. Assigning another axis copies its settings.
Plot.ValueAxis.SetRange(0, 100);Title property
property Title: string read FTitle write SetTitle;Bold heading centred above the chart; empty means no heading and no space reserved.
Plot.Title := 'Sales 2026';Footnote property
property Footnote: string read FFootnote write SetFootnote;Line of text centred at the bottom of the chart; empty means none.
Plot.Footnote := 'Source: order system';LegendVisible property
property LegendVisible: Boolean read FLegendVisible write SetLegendVisible default True;Shows the legend. It lists every visible non-pie series by Title (or "Series N"), or for a pie chart every drawn slice by point Text (or its argument). Captions that do not fit are shortened with "...".
Plot.LegendVisible := False;LegendPosition property
property LegendPosition: TAtlasPlotLegendPosition read FLegendPosition write SetLegendPosition default lpRight;Side of the chart the legend occupies. On the left or right it is one column, at most two fifths of the width, and entries that do not fit the height are left out. At the top or bottom entries flow into at most three centred rows; the rest are left out. See TAtlasPlotLegendPosition.
Plot.LegendPosition := lpBottom;Rotated property
property Rotated: Boolean read FRotated write SetRotated default False;Swaps the axes: the argument axis runs vertically (bottom to top) and the value axis horizontally, which turns bars into horizontal bars and draws lines sideways. Set ArgumentAxis.Inverted as well to list categories from the top down.
Plot.Rotated := True;
Plot.ArgumentAxis.Inverted := True;Stacking property
property Stacking: TAtlasPlotStacking read FStacking write SetStacking default psNone;Stacks bars on bars and areas on areas; lines, steps and points never stack. Points stack when their arguments are equal; positive and negative values build separate stacks from zero. psStacked100 scales each argument's stack to 100 % of the sum of absolute values. Hidden series leave the stack. Changing it ends any zoom. See TAtlasPlotStacking.
Plot.Stacking := psStacked100;DonutPercent property
property DonutPercent: Integer read FDonutPercent write SetDonutPercent default 0;Size of the hole in a pie chart, as a percentage of the radius: 0 draws a full pie, 45 a typical donut. Values are clamped to 0..90. Has no effect on cartesian charts.
Plot.DonutPercent := 45;AllowZoom property
property AllowZoom: Boolean read FAllowZoom write FAllowZoom default True;Enables mouse zooming: drag a rectangle with the left button (more than 4 pixels each way), turn the wheel over the plot, double-click to reset. ZoomTo, ZoomAround and ResetZoom work regardless.
Plot.AllowZoom := False;AllowPan property
property AllowPan: Boolean read FAllowPan write FAllowPan default True;Enables panning by dragging with the right button inside the plot. PanBy works regardless. Consider switching it off when the chart has a PopupMenu, since both use the right button.
Plot.AllowPan := False;Align property
property Align;Standard VCL alignment, published.
Anchors property
property Anchors;Standard VCL anchors, published.
Color property
property Color default clWhite;Background of the whole chart and the plot area. It also outlines pie slices and point dots, and area fills are the series colour mixed 55 % toward it. Default clWhite.
Plot.Color := clBtnFace;Constraints property
property Constraints;Standard VCL size constraints, published.
Enabled property
property Enabled;Standard VCL property; a disabled chart still paints but receives no mouse input.
Font property
property Font;Font of every text. All spacing derives from its line height, so a larger font gives a roomier layout and the chart follows DPI changes without separate scaling. The title uses it in bold; its colour is the text colour, also in SVG output.
Plot.Font.Size := 11;ParentFont property
property ParentFont;Standard VCL property: take the parent's font.
ParentShowHint property
property ParentShowHint;Standard VCL property, published.
ShowHint property
property ShowHint;Standard VCL hint display. The chart has no built-in point hints; set the inherited Hint from OnMouseMove with HitTest.
TabOrder property
property TabOrder;Standard VCL tab order.
TabStop property
property TabStop;When True, clicking the chart gives it the focus, which also makes it the target of wheel messages. There is no keyboard navigation.
Visible property
property Visible;Standard VCL visibility. A hidden chart can still render and export.
Events
OnPointClick event
property OnPointClick: TAtlasPlotPointEvent read FOnPointClick write FOnPointClick;Fires when the left button is released over a bar, vertex, point or slice (as HitTest sees it) and the press did not become a zoom drag. Receives the series and the point index. Fires after OnClick. See TAtlasPlotPointEvent.
Plot.OnPointClick := PointClicked;OnZoom event
property OnZoom: TNotifyEvent read FOnZoom write FOnZoom;Fires after every change of the zoom window: ZoomTo, a mouse zoom, each step of a pan, a wheel step, and ResetZoom when the chart was zoomed. Read Zoomed and the axes' ViewMin/ViewMax (after the next render) to follow it.
Plot.OnZoom := ZoomChanged;OnClick event
property OnClick;Standard VCL click: fires when the left button is released inside the control, before OnPointClick, also at the end of a zoom drag. Use ScreenToClient(Mouse.CursorPos) with PixelToValues or ValuesToPixel to relate it to the data.
OnDblClick event
property OnDblClick;Standard VCL double click. It fires before the chart resets the zoom (when AllowZoom is True).
OnMouseDown event
property OnMouseDown;Standard VCL mouse event; the chart's own zoom and pan handling runs as well.
OnMouseMove event
property OnMouseMove;Standard VCL mouse event. Combine it with PixelToValues and HitTest for a live read-out of the position under the cursor.
OnMouseUp event
property OnMouseUp;Standard VCL mouse event; fires before OnPointClick.
OnResize event
property OnResize;Standard VCL resize event. The chart repaints itself at the new size.
Methods
BeginUpdate method
procedure BeginUpdate;Starts a batch. While at least one batch is open, series, axis and layout changes neither repaint the chart nor notify change listeners. Calls nest; always pair with EndUpdate in a try ... finally block. OnZoom still fires inside a batch.
Plot.BeginUpdate;
try
Plot.Title := 'Regions';
Sales.AddY(42, 'North');
Sales.AddY(35, 'South');
finally
Plot.EndUpdate; // one repaint
end;EndUpdate method
procedure EndUpdate;Closes a batch. When the outermost batch closes the chart repaints once and every change listener is called once. An EndUpdate without a matching BeginUpdate does nothing.
AddChangeListener method
procedure AddChangeListener(const Listener: TNotifyEvent);Registers a method that is called, with the chart as Sender, after any change to series, points, axes, titles, legend, rotation, stacking, donut size or zoom; once per BeginUpdate / EndUpdate batch. Font and Color changes repaint without notifying. Adding the same method twice registers it once. Intended for companion controls (a data grid showing the chart, a summary label). A listener may remove itself while being called.
Plot.AddChangeListener(Watcher.ChartChanged);RemoveChangeListener method
procedure RemoveChangeListener(const Listener: TNotifyEvent);Unregisters a listener added with AddChangeListener. Call it before the listening object is freed. Removing a method that is not registered does nothing.
Plot.RemoveChangeListener(Watcher.ChartChanged);AddSeries method
function AddSeries(const Title: string; Kind: TAtlasPlotKind = pkLine; Color: TColor = clDefault): TAtlasPlotSeries;Appends a new series to Series and returns it. Title appears in the legend and in CSV output. Kind selects line, step, area, bar, point or pie drawing (see TAtlasPlotKind). clDefault takes the next colour of the built-in palette (see SeriesColor). The chart owns the series; do not free it yourself unless you mean to remove it.
Sales := Plot.AddSeries('2026', pkBar);
Orders := Plot.AddSeries('Orders', pkLine, clMaroon);Clear method
procedure Clear;Removes every series and ends any zoom. Axis settings, titles, stacking and the other layout properties are kept. References to the removed series become invalid.
Plot.Clear;SeriesColor method
function SeriesColor(Index: Integer): TColor;The colour series Index is drawn in: its own Color, or when that is clDefault, entry Index mod 10 of a fixed ten-colour palette that starts blue, orange, green, red. Pie slices use the same palette by point index instead.
Swatch.Brush.Color := Plot.SeriesColor(0);AddTrendLine method
function AddTrendLine(Source: TAtlasPlotSeries): TAtlasPlotSeries;Adds a straight least-squares line fitted to the values of Source and returns it: a pkLine series titled Source.Title + ' trend' with two points, at the smallest and largest argument of Source. Gaps are ignored. The result is a snapshot: it does not follow later edits of Source; delete it and add it again after changing the data.
Raises EAtlasPlotError when Source is nil or belongs to another chart, has fewer than two values, or all its values share one argument. A failed call adds nothing.
Plot.AddTrendLine(Sales).LineWidth := 1;AddMovingAverage method
function AddMovingAverage(Source: TAtlasPlotSeries; Period: Integer): TAtlasPlotSeries;Adds a trailing simple moving average of Source and returns it: a pkLine series titled Format('%s avg(%d)', [Title, Period]). Each output point sits at the argument of the value that completes its window, so the result has ValueCount - Period + 1 points. Gaps are skipped, not reset: the window runs across them and the average does not break. A snapshot, like AddTrendLine.
Raises EAtlasPlotError when Source is nil or belongs to another chart, or when Period is below 1 or above Source.ValueCount.
Plot.AddMovingAverage(Daily, 7).LineWidth := 3;Render method
procedure Render(Surface: TAtlasPlotSurface; const Bounds: TRect);Draws the whole chart (background, title, footnote, legend, axes, series and marks) onto any drawing surface inside Bounds. This is the single layout path every output uses; implement TAtlasPlotSurface to draw somewhere new, or pass a TAtlasCanvasSurface or TAtlasSvgSurface to place several charts on one page.
Afterwards PlotRect, HitTest, ValuesToPixel, PixelToValues and the axes' ViewMin/ViewMax describe this render. Unlike RenderTo, CreateBitmap, ToSVG and SaveToFile, Render does not restore the on-screen layout afterwards; call Repaint on a visible chart when you are done. Raises EAtlasPlotError when Surface is nil. A target too small for a plot draws only the background, title and footnote.
RenderTo method
procedure RenderTo(Target: TCanvas; const Bounds: TRect);Draws the chart onto any VCL canvas inside Bounds: a bitmap, a metafile canvas, Printer.Canvas, or the canvas of another control. Text sizes follow the chart's Font as the target canvas measures it. When the chart has a window, its on-screen layout is re-run afterwards so mouse hit testing keeps matching what the user sees.
Plot.RenderTo(Bitmap.Canvas, Rect(0, 0, Bitmap.Width, Bitmap.Height));ZoomTo method
procedure ZoomTo(const ArgMin, ArgMax, ValMin, ValMax: Double);Shows exactly the given window, in data units, on both axes (no rounding to whole steps), sets Zoomed, repaints and fires OnZoom. While zoomed, the window replaces both the data range and any manual axis range.
Raises EAtlasPlotError and changes nothing when a value is not finite or beyond 1E100, when a minimum is not below its maximum, when a logarithmic axis would reach zero or below, or when a span is smaller than about 1E-12 of its magnitude. With psStacked100 the value window is in percent.
Plot.ZoomTo(2, 6, 0, 40);ResetZoom method
procedure ResetZoom;Ends the zoom, returning to the automatic or manual axis ranges, repaints and fires OnZoom. Does nothing, and fires nothing, when the chart is not zoomed. Double-clicking the chart calls it when AllowZoom is True.
if Plot.Zoomed then Plot.ResetZoom;PanBy method
procedure PanBy(DeltaX, DeltaY: Integer);Moves the visible window as if the content were dragged by DeltaX, DeltaY pixels: a positive DeltaX reveals lower arguments, a positive DeltaY moves the content down. Works against the most recent render and leaves the chart zoomed. Does nothing when that render had no cartesian plot (nothing drawn yet, a pie, or a target too small). Can raise EAtlasPlotError at the edge of the supported range; right-drag panning ignores that error.
Plot.PanBy(Plot.PlotRect.Width div 2, 0);ZoomAround method
procedure ZoomAround(X, Y: Integer; const Factor: Double);Scales the visible window by Factor about the pixel X, Y, keeping the data value under that pixel in place: 0.5 halves the window, 2 doubles it. The mouse wheel uses 0.8 (wheel up) and 1.25 (wheel down). Works against the most recent render and does nothing without a cartesian plot. Raises EAtlasPlotError when Factor is not a positive finite number or the resulting window is invalid.
Plot.ZoomAround(Plot.PlotRect.CenterPoint.X, Plot.PlotRect.CenterPoint.Y, 0.5);HitTest method
function HitTest(X, Y: Integer; out SeriesIndex, PointIndex: Integer): Boolean;Reports which point is drawn at pixel X, Y of the most recent render. A bar answers inside its rectangle; a line, step, area or point vertex within 5 pixels (or its dot radius plus 2); a pie or donut slice inside its ring segment. Where regions overlap, the one drawn last wins. Areas answer only at their vertices, not across the fill. Points outside the plot area (beyond a manual range or zoom window) are not hit. Returns False with both indexes -1 when nothing is there.
if Plot.HitTest(X, Y, SeriesIndex, PointIndex) then
Caption := Plot.Series[SeriesIndex].Title;ValuesToPixel method
function ValuesToPixel(const Arg, Val: Double; out Pixel: TPoint): Boolean;Converts data values to a pixel of the most recent render, honouring logarithmic, inverted and rotated axes. Returns False (and Pixel = (0, 0)) when that render had no cartesian plot, for example before the first paint or for a pie. Values outside the visible range map outside PlotRect. For stacked series pass the stacked total, not the point's own value, to reach the top of its bar or area.
if Plot.ValuesToPixel(1, 10, Pixel) then
Caption := Format('%d, %d', [Pixel.X, Pixel.Y]);PixelToValues method
function PixelToValues(X, Y: Integer; out Arg, Val: Double): Boolean;Converts a pixel of the most recent render back to data values (Arg on the argument axis, Val on the value axis); the inverse of ValuesToPixel. Returns False, with both values 0, when that render had no cartesian plot. Pixels outside PlotRect are extrapolated. With a date/time axis Arg is a TDateTime.
if Plot.PixelToValues(X, Y, Arg, Val) then
Caption := Format('x = %.2f, y = %.2f', [Arg, Val]);CreateBitmap method
function CreateBitmap(AWidth, AHeight: Integer): Vcl.Graphics.TBitmap;Renders the chart into a new 24-bit bitmap of the given size and returns it; the caller frees it. Each side must be 1 to 16384 pixels, otherwise EAtlasPlotError is raised. Does not change the on-screen layout.
Bitmap := Plot.CreateBitmap(800, 500);
try
Image1.Picture.Assign(Bitmap);
finally
Bitmap.Free;
end;ToSVG method
function ToSVG(AWidth, AHeight: Integer): string;Renders the chart as an SVG document of the given size and returns the text (declared UTF-8). Text is escaped, series are clipped to the plot area with clipPath, fonts are referenced by name, not embedded. Each side must be 1 to 16384 pixels. Does not change the on-screen layout.
Svg := Plot.ToSVG(800, 500);SaveToFile method
procedure SaveToFile(const FileName: string; AWidth: Integer = 0; AHeight: Integer = 0);Writes the chart to a file whose extension selects the format: .png, .bmp, .emf (enhanced metafile) and .svg render the chart at AWidth x AHeight pixels (0 means the control's current Width or Height); .csv writes DataToCSV as UTF-8 without BOM and ignores the size. The file is written to FileName + '.part' and renamed over the target, so a failed export leaves any previous file intact.
Raises EAtlasPlotError for any other extension or an image size outside 1 to 16384; a missing folder or a locked file raises the usual stream or OS exception. Does not change the on-screen layout.
Plot.SaveToFile('sales.png', 800, 500);
Plot.SaveToFile('sales.svg', 800, 500);
Plot.SaveToFile('sales.csv');CopyToClipboard method
procedure CopyToClipboard;Places a bitmap of the chart, at the control's current size, on the clipboard. Clipboard output has not been covered by automated tests.
Plot.CopyToClipboard;DataToCSV method
function DataToCSV: string;Returns every point as CSV text with CRLF line ends. The header is series,kind,x,y,text; kind is line, step, area, bar, point or pie; numbers always use . as decimal separator and keep up to 15 significant digits; a gap has an empty y; fields holding a comma, quote or line break are quoted. Only titles, kinds and points are exported: colours, visibility, marks and line widths are not, and series without points produce no rows.
Csv := Plot.DataToCSV;DataFromCSV method
procedure DataFromCSV(const Text: string);Replaces every series with the data in Text, in the format DataToCSV writes. A leading byte order mark is ignored. Consecutive rows with the same title and kind form one series (two adjacent series sharing both would merge); an empty y becomes a gap. Imported series get default colours, marks and widths, and the zoom is reset.
The whole text is validated first: a missing header, a row without five fields, an unknown kind, a malformed or out-of-range number, a negative pie slice or an unterminated quote raises EAtlasPlotError and leaves the chart unchanged. References to the old series become invalid after a successful import.
Plot.DataFromCSV(TFile.ReadAllText('sales.csv', TEncoding.UTF8));Examples
Bar chart on a form, reporting clicks
A form built in code with two grouped bar series whose point texts become category labels. Clicking a bar shows its series, category and value.
uses
System.Classes, System.SysUtils, Vcl.Controls, Vcl.Forms, Vcl.StdCtrls,
Atlas.Plot, Atlas.PlotSeries;
type
TSalesForm = class(TForm)
private
FPlot: TAtlasPlot;
FStatus: TLabel;
procedure PointClicked(Sender: TObject; Series: TAtlasPlotSeries; PointIndex: Integer);
public
constructor Create(AOwner: TComponent); override;
end;
constructor TSalesForm.Create(AOwner: TComponent);
var
Plan, Actual: TAtlasPlotSeries;
begin
inherited CreateNew(AOwner);
Caption := 'Sales by region';
FStatus := TLabel.Create(Self);
FStatus.Parent := Self;
FStatus.Align := alBottom;
FPlot := TAtlasPlot.Create(Self);
FPlot.Parent := Self;
FPlot.Align := alClient;
FPlot.Title := 'Plan and result by region';
FPlot.OnPointClick := PointClicked;
FPlot.BeginUpdate;
try
Plan := FPlot.AddSeries('Plan', pkBar);
Actual := FPlot.AddSeries('Result', pkBar);
Actual.Marks := pmValue;
Plan.AddY(42, 'North');
Actual.AddY(45.5, 'North');
Plan.AddY(35, 'South');
Actual.AddY(31, 'South');
Plan.AddY(51, 'East');
Actual.AddY(56, 'East');
finally
FPlot.EndUpdate;
end;
end;
procedure TSalesForm.PointClicked(Sender: TObject; Series: TAtlasPlotSeries; PointIndex: Integer);
begin
FStatus.Caption := Format('%s, %s: %g',
[Series.Title, Series[PointIndex].Text, Series[PointIndex].Y]);
end;
Export without a window
An off-screen chart, created with no owner, rendered to PNG, SVG and CSV files. Works in console programs.
uses
System.SysUtils, Atlas.Plot, Atlas.PlotSeries;
procedure ExportVisits(const Folder: string);
var
Plot: TAtlasPlot;
Visits: TAtlasPlotSeries;
Base: string;
begin
Base := IncludeTrailingPathDelimiter(Folder) + 'visits';
Plot := TAtlasPlot.Create(nil);
try
Plot.Title := 'Visits per day';
Plot.LegendVisible := False;
Visits := Plot.AddSeries('Visits', pkArea);
Visits.AddY(120, 'Mon');
Visits.AddY(135, 'Tue');
Visits.AddY(128, 'Wed');
Visits.AddY(160, 'Thu');
Visits.AddY(98, 'Fri');
Plot.SaveToFile(Base + '.png', 800, 450);
Plot.SaveToFile(Base + '.svg', 800, 450);
Plot.SaveToFile(Base + '.csv');
finally
Plot.Free;
end;
end;
Print a chart
Draws the chart across the top half of a printed page. There is no print dialog or preview; printing on hardware has not been tested.
uses
System.Types, Vcl.Printers, Atlas.Plot;
procedure PrintChart(Plot: TAtlasPlot);
begin
Printer.BeginDoc;
try
Plot.RenderTo(Printer.Canvas, Rect(0, 0, Printer.PageWidth, Printer.PageHeight div 2));
finally
Printer.EndDoc;
end;
end;
Follow changes from another object
A change listener is called once per batch, so a companion object can refresh itself after the chart changes.
uses
Atlas.Plot, Atlas.PlotSeries;
type
TChartWatcher = class
private
FChanges: Integer;
procedure ChartChanged(Sender: TObject);
public
property Changes: Integer read FChanges;
end;
procedure TChartWatcher.ChartChanged(Sender: TObject);
begin
Inc(FChanges);
end;
procedure RefreshTwice(Plot: TAtlasPlot; Watcher: TChartWatcher);
begin
Plot.AddChangeListener(Watcher.ChartChanged);
try
Plot.BeginUpdate;
try
Plot.Title := 'Batch';
Plot.AddSeries('A').AddY(1);
finally
Plot.EndUpdate; // Watcher.Changes grows by one for the whole batch
end;
Plot.Footnote := 'Single change'; // and by one more here
finally
Plot.RemoveChangeListener(Watcher.ChartChanged);
end;
end;
Related
TAtlasPlotSeries · TAtlasPlotAxis · TAtlasPlotSeriesList · TAtlasPlotSurface · EAtlasPlotError · TAtlasPlotStacking · TAtlasPlotLegendPosition · TAtlasPlotPointEvent