Using Themes with TeeChart

Introduction

 

“Themes” allow changing all visual formatting properties of Charts with a single click or line of code.

The default look of a TeeChart hasn’t been changed for many years. This is on purpose, as it might be annoying to discover existing charts have  completely different colors or font styles just because a new version has been installed.

 

Default TeeChart Theme

Time goes fast, and what it looked “modern” in the past, might look “old fashioned” in the future.  (If we wait a little bit more, maybe the old look will be modern again. Trends are cycling  :-).

 

Choosing a Theme

 

The chart editor dialog (in the “Pro” version of TeeChart) includes a Theme tab where you can choose and apply a Theme both at design-time and run-time:

TeeChart Themes Editor

 

 

Clicking the bottom-right “Apply” button will change all necessary properties in the edited chart, like fonts, colors, pens and brushes.

 

 

Applying Themes by code

 

Adding the Themes unit to the “uses” clause ( VCLTee.TeeThemes or FMXTee.Themes) enables using the predefined theme classes or creating custom themes.

The above picture shows the “Flat” theme selected in the editor. This is just a small class named “TFlatTheme”, derived from a base TChartTheme class.

Applying the Flat theme at runtime by code:

uses VCLTee.TeeThemes; // FMXTee.Themes <--- FireMonkey

ApplyChartTheme( TFlatTheme, Chart1 );

 

Available Themes

 

There are several theme classes included in the Themes unit.

A list of themes can be obtained with the global ChartThemes variable. Each item in the list is a TChartTheme class that can be passed to ApplyChartTheme method.  This is the list displayed at the above Themes editor dialog.

 

Creating custom Themes

 

Customizing a theme to apply it to other charts is really easy.
A “theme” is nothing more, and nothing else, than a normal Chart.

That means, any existing chart can be used as a theme for any other chart.

For example, the chart below (“BlueChart”) has been manually customized in a couple of minutes, changing font styles to “Segoe UI”, changing the panel color to white, setting series color and border color to blue, hidding the axes ticks, etc.

 

TeeChart Custom Theme

 

This chart can now be used as a new custom Theme, for example to change the look of the above first chart with this simple code:

// Apply ( Destination Chart  <----  Origin Chart )

TThemesList.Apply( Chart1, BlueChart );

 

Chart1 (the first chart in this post), has now been changed to:

 

TeeChart_with_custom_Theme

 

Note in the above chart that when applying a theme, properties that affect the appearance are the only ones modified. This includes font styles, colors and transparencies.  Visibility of elements (chart legend, series marks, 3D etc) are left unchanged.

 

Data Color Palette

 

Colors used to fill individual series points (like the colors for the above Bar items) are chosen from a color palette.  This is essentially an “Array of TColor”.

TeeChart includes several predefined color palettes. Each palette is identified by a number.  The list of available palettes is located at the chart editor “General -> Palette” tab:

TeeChart_Color_Palettes

 

 

This dialog allows changing the predefined color palette or creating custom palettes. Colors can be clicked to change them, and the buttons allow adding,  removing or reordering colors.

Changing a color palette by code is just changing a chart property:

// Predefined palettes, from 1 to 19

Chart1.ColorPaletteIndex := 5 ;

 

An array of colors can also be used as a palette:

 

procedure TForm1.Button4Click(Sender: TObject);
const
  MyColors : Array[0..7] of TColor = (
    $FF0000,
    $0000FF,
    $00FF00,
    $00CCFF,
    $404040,
    $00FFFF,
    $C000FF,
    $FFFFFF );

begin
  TColorPalettes.ApplyPalette( Chart1, MyColors );
  Chart1.Invalidate;
end;

 

Color palettes and themes are totally independent. Applying a theme to a chart will replace the chart colors with the theme colors (a theme is just a normal chart).

After applying a theme, the color palette can be changed at any time.

 

 

Registering Custom Themes

 

(Advanced)

Custom themes (charts that can be used as themes for other charts) can also be “registered” with the purpose of showing them at the Themes Editor list.

This is done with the help of small class derived from base TChartTheme:

type
  TMyBlueTheme=class(TChartTheme)
  public
    procedure Apply; override;
    function Description:string; override;
  end;

procedure TMyBlueTheme.Apply;
var tmp : TForm1;
begin
  inherited;

  tmp:=TForm1.Create(nil);
  try
    TThemesList.Apply(Self.Chart, tmp.Chart2);
  finally
    tmp.Free;
  end;
end;

function TMyBlueTheme.Description:string;
begin
  result:='My Blue Theme';
end;

// And then calling a method to register the class:

RegisterChartThemes([TMyBlueTheme]);

This is how existing themes are internally registered.

The Apply method can also be used to perform any additional settings or changing any other property.

 

Download example

 

Click here to download a small VCL example project showing the above code.

Note: The “Pro” version of TeeChart is required.

 

TeeChart and GDI+ inside a DLL

 

TeeChart VCL controls use GDI+ (Windows graphics library) by default in VCL applications.

 

TeeChart GDI+ editor dialog
TeeChart GDI+ editor dialog

 

NOTE: The fix indicated below has been already included in the latest VCL version: 2014.11.140512    Download link

There is a “problem” with GDI+ when using it inside a DLL. GDI+ needs to be initialized before using it, and the initialization should be done by the caller EXE process, not by the DLL itself.

(Microsoft information about this can be found here in this link)

This is why the Embarcadero RAD Studio RTL WinApi.GDIPOBJ.pas unit, at the bottom of the file initialization section, checks “if not IsLibrary” to initialize GDI+ only when the unit is used by an executable application.

The problem is, if you have a DLL that contains chart controls, and if GDI+ has not been correctly initialized, an Access Violation exception will be raised from code inside the Windows GDI+ gdiplus.dll !

The solution is quite easy. In your EXE application, before calling any DLL function, add this code to initialize GDI+ :

uses WinAPI.GDIPObj, WinAPI.GDIPApi ;

// Initialize StartupInput structure
StartupInput.DebugEventCallback := nil;
StartupInput.SuppressBackgroundThread := False;
StartupInput.SuppressExternalCodecs := False;
StartupInput.GdiplusVersion := 1;

GdiplusStartup(gdiplusToken, @StartupInput, nil);

 

It is also recommended (although it doesn’t seem mandatory), to uninitialize GDI+, as one of your EXE last steps:

GdiplusShutdown(gdiplusToken);

 

The next TeeChart release (very soon !) will include a small fix to improve this situation: if GDI+ is not initialized for any reason, it will fallback to “old” GDI graphics instead, avoiding the exception.

Click here to download a simple test project made in Delphi with RAD XE5 that includes an EXE and a DLL. The DLL contains a Form1 with a Chart1. The EXE main unit initializes GDI+ and calls the DLL to show the chart.