Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_5887.html
 

Сглаженные кривые в TeeChart

Опубликовано 14.03.2013 г. 18:17

В этот день 3 года назад в блоге появилась первая запись про копирование файлов, а сегодня простенькая статья-заметка (уже 123-я) про использование сглаженных кривых в TeeChart.

В рабочем проекте присутствует достаточно большое число различных графиков и диаграмм для которых используется TeeChart. В основном по оси Х на графике всегда изображены годы. Интервал сравнительно небольшой 20-30 лет. Все данные обычно изображаются в виде ломаных, что выглядит не очень, скажем, элегантно. В связи с этим решили не так давно нарисовать сглаженные кривые, чтобы у нас не углами линии шли, а более "симпотично" (:
Для этих целей TeeChart представляет нам класс TSmoothingFunction, реализующий сглаживание значений серии по точкам. Алгоритм использования весьма прост. Имеется исходная серия - Series1, на основании ее строится вторая серия Series2. Первая серия устанавливается в качестве источника данных для второй - Series2.DataSource := Series1. Далее создается экземпляр TSmoothingFunction, для которого в качестве родительской серии выбирается вторая серия: Smooth.ParentSeries := Series2; В общем то это все шаги которые необходимо выполнить, чтобы получить вместо ломаной, красивую сглаженную кривую, проходящую через искомые точки. При изменении исходной серии необходимо вызвать метод CheckDataSource() новой серии.

Для удобства использования (в нашем случае серии почти всегда созадются динамически) был написан небольшой вспомогательный класс. Суть класса в том, что на вход мы поадем серию исходных данных. А экземпляр производит несколько манипуляций. Во-первых создает сглаженную серию, копирует название и цвет исходной. Далее он убирает исходную серию с графика, из легенды, из списка серий, и помещает себя на диаграмму.
В качестве внешего интерфейса класс имеет одно свойство - ссылка на исходную серию, и метод обновления. Таким образом, сначала мы созадем и заполняем исходные серии. Далее на их основе создаем экземпляры классов-оберток. Ссылки на исходные серии мы более не храним, и работаем через свойство TSmootSeriesData.DataSeries, и используем метод Update для обновления и перерисовки.

С точки зрения кода, все вышеперечисленное выглядит следующим образом:

type
    TSmoothSeriesData = class(TObject)
      strict private
        FData :   TCustomSeries;
        FSmooth : TCustomSeries;
        FFunc :   TSmoothingFunction;
        procedure InitSmoothing();

        function getVisible():boolean;
        procedure setVisible(value : boolean);
      public
        constructor Create(Data : TCustomSeries);
        procedure Update();

        property DataSeries : TCustomSeries read FData;
        property Visible : boolean read getVisible write setVisible;
        property SmoothSeries : TCustomSeries read FSmooth;
    end;

implementation


{$REGION '--------------------- TSmoothSeriesData ---------------------'}

constructor TSmoothSeriesData.Create(Data: TCustomSeries);
begin
    inherited Create();
    FData := data;

    with FData do begin
        ShowInEditor := false;
        ShowInLegend := false;
        Visible := false;
        FData.ParentChart := nil;
    end;

    InitSmoothing();
end;

procedure TSmoothSeriesData.InitSmoothing();
begin
    FSmooth := TLineSeries.Create(FData.Owner);
    FSmooth.Title := FData.Title;
    FSmooth.Color := FData.Color;
    FSmooth.DataSource := FData;

    FFunc := TSmoothingFunction.Create(FData.Owner);
    FFunc.ParentSeries := FSmooth;
    FFunc.Factor := 12;

    (FSmooth.Owner as TChart).AddSeries(FSmooth);
end;

procedure TSmoothSeriesData.setVisible(value: boolean);
begin
    FSmooth.Visible := value;
end;

function TSmoothSeriesData.getVisible: boolean;
begin
    result := FSmooth.Visible;
end;


procedure TSmoothSeriesData.Update();
begin
    FSmooth.CheckDataSource();
end;

{$ENDREGION}

Пригодится в использовании и типизированный словарик     TSmoothSeriesDictionary<T> = TObjectDictionary<T, TSmoothSeriesData>; В качестве параметра T могут выступть как Integer типы, так и любое перечисление. Если на графике вы выводите несколько серий, то все равно каждая из них будет иметь какой то идентификтор, который и можно испоьзовать в качестве T-параметра.

Напомню, что доступ к исходной серии можно получить через свойство DataSeries, после чего обновить исходные значения, а затем вызвать метод Update() для перерисовки сглаженной серии.

 

UPD: в версии TeeChart 2013 серии TLineSeries имеют булевое свойство Smoothed, которе как раз таки позволяет добиться эффекта сглаженных ломаных.

Метки:  TeeChart 

Комментарии

CorsaiR
15.03.2013 в 18:26
Еще, насколько я помню, TSmoothingFunction доступно только в Pro версии TeeChart. В той, что идет с Delphi сглаживания нет.
teran
16.03.2013 в 01:08
Проверил в ХЕ3 (стандартный TeeChart), TSmoothingFunction есть.
Василий
26.03.2013 в 13:04
в XE2 в uses VCLTee.TeeSpline
а D2007 нету (((
teran
26.03.2013 в 14:48
да, следовало ожидать, что в 2007й такого нет. TeeChart то тоже на месте не стоит, видимо этот функционал появился позже 2007го года.
Вопрос в том, что может там можно обвноление поставить какое-нибудь?
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно