TAChart documentation/ru
│
English (en) │
русский (ru) │
українська (uk) │
中文(中国大陆) (zh_CN) │
Обзор
TAChart - это пакет для рисования графиков, схем и других диаграмм. Он сопоставим по функциям, но не полностью совместим с Delphi'йским TeeChart. Одно существенное отличие состоит в том, что некоторые функции (например, источники данных и преобразования осей) реализуются через отдельные компоненты, а не через простые свойства диаграммы. Такая конструкция обеспечивает повышенную гибкость и возможность повторного использования кода, но за счет немного более сложного API.
Этот документ предоставляет краткий, но всесторонний обзор концепций, функций и компонентов TAChart. Пошаговое изучение см. в TAChart Tutorial: Getting started и других учебных пособиях.
В документации описан пакет TAChart, который можно найти в последней версии Lazarus для разработки. Некоторые функции могут быть недоступны в официальной версии Lazarus. Мы рекомендуем вам использовать эту последнюю версию документа, поскольку в ней исправлены и улучшены более старые описания в предыдущих версиях, а также тот факт, что в нее включены сведения о новейших функциях.
Тем не менее, вы можете посмотреть старую версию этого документа, чтобы увидеть состояние документации на момент выпуска Lazarus 1.0.
Серии
Серии (графики, диаграммы) являются центральной частью TAChart. Их иерархия проиллюстрирована на рисунке. Серии, наследуемые от TCustomChartSeries, представляют данные, взятые из ChartSource графическим способом, таким как линии или столбцы; другие серии получают свои данные по-другому.
Диаграмма со сплошной линией
Это самый простой тип графика, представляющий «бесконечную» вертикальную или горизонтальную линию. Его можно использовать в качестве «центральной оси» в графиках функций или в качестве перетаскиваемой линии маркера.
Кроме того, установив Active
= true, Pen.Style = psClear
и UseBounds = true
и соответствующий AxisIndexX
, он становится «расширителем оси», гарантируя, что данное значение Position
всегда будет включена в диапазон оси.
Основные виды диаграмм
Основные виды графиков используются наиболее часто и включают в себя line, bar и area серии. Все основные серии могут быть «сложены» с помощью источников со множеством значений. Также все базовые серии полностью поддерживают вращение и 3-D рисунок.
Line-диаграмма
TLineSeries
можно использовать для рисования заданного набора точек, опционально помечая каждую точку данных символом и/или соединяя точки данных линией. Цвет ряда линий определяется свойством SeriesColor
.
ColorEach
позволяет управлять окраской отдельных точек данных и смежных сегментов линии (цвет точки данных предоставляется источником диаграммы):
ceNone
- нет отдельной окраски, даже если цвета назначаются элементу данных диаграммы.cePoint
- раскрасить только символ точки данных, но не отрезок.ceLineAfter
- применить цвет точки данных к сегменту линии, следующему за точкой данныхceLineBefore
- применить цвет точки данных к сегменту перед точкой данныхcePointAndLineAfter, cePointAndLineBefore
- как и раньше, но раскрашивает и символ точки данных.
Вы можете получить «пошаговый» вид, установив для свойства LineType
значение ltStepXY
или ltStepYX
.
Используя источник со множеством значений, TLineSeries
может обрабатывать несколько значений y для каждого значения x. Если для свойства Stacked
установлено значение true
, то отдельные значения y отображаются в виде ряда, то есть второе значение y добавляется к первому, а третье значение y ко второму значению и т.д. Обратите внимание, однако, что в отличие от серий bar или area, может быть неясно, что значения данных сгруппированы, и поэтому укладка в виде рядов обычно не рекомендуется в сериях line.
Fast lines
Некоторые графические пакеты включают в себя специальный график "fast line" для быстрого рисования серии линий из чрезвычайно больших наборов данных (более 10000 точек). TAChart, напротив, содержит оптимизированный быстрый путь внутри стандартного кода серии строк, который обеспечивает сопоставимую скорость рисования.
Серия линий будет нарисована очень быстро, если все следующее верно:
- Нет отметок.
- Нет указателей.
LineType
не установлено в значениеltFromOrigin
.
Некоторые операционные системы/наборы виджетов могут дополнительно требовать, чтобы свойствам были установлены следующие значения LinePen.Style=psSolid
и LinePen.Width=1
.
Дополнительного быстродействия можно добиться, если установить Source.Sorted=true
.
Вы можете измерить скорость рисования линий на вашей платформе с помощью демо «line».
Point-диаграмма
TLineSeries
можно нарисовать как «серию точек», показывающую только символы в позиции точек данных и скрывающую соединительные линии, установив для ShowPoints
значение True
и LineType
для ltNone
. Обратите внимание, что SeriesColor
применяется только к соединительным линиям; чтобы указать цвет точек, измените Pointer.Brush.Color
для заливки и/или Pointer.Pen.Color
для цвета линии границы. Свойство Pointer
также предоставляет доступ к фигурам (круг, рамка и т.д.) символов (Style
).
Bar-диаграмма
TBarSeries
представляет данные в виде набора полос, простирающихся от ZeroLevel
до точек данных.
Вы можете контролировать ширину полосы с помощью свойства BarWidthPercent
. Обратите внимание, что оно измеряется относительно соседних полос. Если значения X не равноудалены, полосы будут иметь различную ширину. Чтобы предотвратить это, установите BarWidthStyle=bwPercentMin
.
Вы можете рисовать несколько полос бок о бок, используя свойство BarOffsetPercent
.
Используйте несколько значений Y для создания ряда полос с накоплением (Stacked=true
). Начиная с Lazarus 2.0, несколько значений Y также могут отображаться в расположении рядом (Stacked=false
).
В дополнение к прямоугольным полосам данные могут быть представлены альтернативными формами: цилиндр, шестиугольная призма, пирамида или конус - см. свойство BarShape
, которое поддерживает следующие значения: bsRectangular, bsCylindrical, bsHexPrism, bsPyramid, bsConical
. Кроме того, событие OnCustomDrawBar
позволяет рисовать столбцы любым заданным пользователем способом.
Area-диаграмма
TAreaSeries
представляет данные в виде многоугольника, продолжающегося вниз от точек данных, либо до линии ZeroLevel
, либо к бесконечности (если UseZeroLevel=false
).
Вы можете получить «пошаговый» вид, задав свойство ConnectType
.
Как и TBarSeries
и TLineSeries
, ряд областей может принимать несколько значений Y
для одного и того же X
из источника данных со множеством значений. Эти значения y отображаются в стопке, если для свойства Stacked
установлено значение True
(его значение по умолчанию). Используйте компонент ChartStyles, чтобы определить внешний вид отдельных слоев. (Обратите внимание, что в версиях Lazarus 1.8.x или более ранних ChartStyles не окрашивают последовательно перекрывающиеся слои).
Свойство Banded
(доступно в Lazarus v2.0 +), если установлено в true, подавляет рисование самого низкого уровня стека. Таким образом, полоса значений данных может быть выделена: используйте источник диаграмм с двумя значениями Y - установите первое значение Y на минимум, а второе значение Y на максимальный уровень диапазона. В качестве альтернативы, ширина полосы может быть указана во втором значении Y, если оба свойства Banded
и Stacked
установлены в true.
Поддержку нескольких значений Y следует применять с осторожностью: при суммировании НЕположительных значений могут получаться графики, которые трудно понять, а ряд непакетированных областей (Stacked=false
) может пострадать от того, что данные покрываются другими значениями Y. Кроме того, ZeroLevel
следует включать только в самый низкий уровень стека, чтобы избежать необычных результатов.
Трехмерное представление серии может быть получено, если для Depth
установлено положительное значение, например, 10 или 20. Обратите внимание, что алгоритм рисования очень прост и, скорее всего, даст неправильно отображение при пересечении кривых, или при отключенных свойствах укладки и объединения.
Диаграмма со множеством значений
Для графика со множеством значений требуется источник данных со множеством значений и использование дополнительных значений X и/или Y в качестве дополнительных параметров для рисования сложных фигур.
Bubble-диаграмма
TBubbleSeries
представляет данные в виде окружностей переменного радиуса с центром в точках данных. Для этой серии требуется источник с YCount
не менее 2, и в качестве радиуса пузырька используется первое дополнительное значение Y.
Свойство OverrideColor
позволяет установить цвет внутренней части или края каждого пузырька в отдельности.
Диаграмма Box-and-whiskers
TBoxAndWhiskerSeries
представляет данные в виде прямоугольников с центральной линией и двумя Т-образными формами, выступающими в обоих направлениях. Хотя в статистике ящик с усами (диаграмма размаха) должен основываться на конкретных квартилях данных, TAChart не применяет это, позволяя пользователям рисовать произвольные графики.
Иногда можно использовать серии блоков и усов, чтобы представить другие диаграммы другого значения, но схожего внешнего вида, такие как диаграммы Гантта.
Для этой серии требуется источник с YCount
не менее 5, и используются значения Y следующим образом:
Index | Usage |
---|---|
0 | Нижний ус |
1 | Нижняя граница ящика |
2 | Центральная линия |
3 | Верхняя граница ящика |
4 | Верхний ус |
Диаграмма Open-high-low-close
TOpenHighLowCloseSeries
представляет данные в виде вертикальных линий с двумя галочками, как описано здесь.
Обычно требуется YCount
не менее 4 и используются значения Y следующим образом:
Свойство | По умолчанию | Использование |
---|---|---|
YIndexLow | 0 | Нижняя точка линии |
YIndexOpen | 1 | Положение галочки слева |
YIndexClose | 2 | Положение галочки справа |
YIndexHigh | 3 | Верхняя точка линии |
Field-диаграмма
TFieldSeries
отображает вектор в каждой точке данных. Вектор рисуется как отрезок с необязательной стрелкой. Линия центрируется по координатам X,Y, хранящимся в источнике диаграммы, ее направление задается дополнительными значениями, хранящимися в XList и YList источника диаграммы. Следовательно, для этого типа серии требуется источник с двумя значениями X и Y:
Поле элемента данных источника | Использование |
---|---|
X | X координата центра линии |
Y | Y координата центра линии |
XList[0] | X координата направления линии |
YList[0] | Y координата направления линии |
Метод AddVector(x,y: Double; vectorx, vectory: Double; ALabel: String = ''; AColor: TColor = clTAColor)
помогает правильно назначить все значения внутреннему списку источника.
Чтобы избежать наложения векторов, вызовите метод Normalize Vector(Length: Double)
,дабы нормализовать их длины так, чтобы самый длинный вектор имел указанную длину.
Параметры стрелки понимаются как проценты от длины вектора, то есть стрелка становится меньше для более коротких векторов.
Круговые диаграммы
Радиальные серии игнорируют преобразования осей. Вы можете увидеть примеры радиальных рядов в demo "radial".
Pie-диаграмма
TPieSeries
рисует круговые диаграммы.
Для каждой точки данных круговая серия интерпретирует значение Y как относительный размер среза, а значение X как расстояние среза от центра круговой диаграммы (только если свойство Exploded
имеет значение true).
Начиная с StartAngle
, круговая диаграмма вращается против часовой стрелки по всему кругу.
Радиус круга можно установить вручную с помощью свойства FixedRadius
или рассчитать автоматически, чтобы вся серия, включая все метки, точно соответствовала родительской диаграмме.
Кольцо можно нарисовать вместо кругового фрагмента, задав свойству InnerRadiusPercent
значение больше 0, но меньше 100 - это определяет радиус внутреннего круга в процентах от общего радиуса.
Цвета кусочка определяются полем Color
элементов данных или жестко закодированной палитрой. Контуры срезов отрисовываются с использованием свойства EdgePen
.
Существует несколько опций для позиционирования метки, управляемых свойством MarkPositions
:
pmpAround
-- отметки рисуются вне круговой диаграммы на продолжении или радиус-векторе для каждого кусочкаpmpInside
--отметки нарисованы внутри каждого кусочкаpmpLeftRight
-- отметки рисуются непосредственно слева или справа от кусочка
MarkDistance
определяет расстояние между начальной точкой метки и меткой. Начальная точка определяется MarkPositionCentered
как периметр круговой диаграммы (false
) или центр (true
). MarkDistancePercent
, если установлено значение true
, интерпретирует Marks.Distance
как процент от радиуса круговой диаграммы. В противном случае оно интерпретируется в единицах изображения.
Если RotateLabels
имеет значение true, каждая метка дополнительно поворачивается, чтобы (если LabelFont.Orientation=0
) она была параллельна радиус-вектору своего кусочка.
Если для значения Y элемента данных установлено значение NaN, он станет скрытым элементом. Если значение X установлено в NaN, элемент не рисуется, но место для него все еще зарезервировано. Это позволяет рисовать «частичные» круговые диаграммы.
Круговые диаграммы имеют ограниченную поддержку для трехмерного рисования. Свойство Depth
определяет толщину круга. Orientation
дополняет нормальный вид (poNormal
) скошенным видом наклонной (poHorHorizontal
) и вертикальной (poVertical
) круговой серии, последние две управляются свойством ViewAngle
в градусах от 0 до 89. Поскольку TAChart не реализует алгоритм истинной скрытой линии/скрытой поверхности, в некоторых комбинациях могут быть некоторые изменения артефактов рисования параметров.
Polar-диаграмма
TPolarSeries
представляет данные в виде точек в полярной системе координат.
Начало полярной системы координат определяется в координатах графа свойствами OriginX
и OriginY
.
Для каждой точки данных значение X интерпретируется как угол в радианах, а значение Y - как расстояние от центра.
TPolarSeries не поддерживает преобразования осей.
Некоторые дополнительные свойства:
CloseCircle
: если имеет значениеtrue
, последняя точка связана с первой.Filled
: если имеет зачениеtrue
, то многоугольник точек серии заполняется с использованием текущего значенияBrush
. ЕслиCloseCircle
равно false, заливка отправляется в начало координат.ShowPoints
: если имеет значениеtrue
, то указатель серии рисуется в позиции каждой точки данных.
Диаграммы с пользовательской отрисовкой
Предоставляет события OnDraw
и OnGetBounds
, чтобы разрешить произвольную пользовательскую отрисовку на TChart. Обратите внимание, что использование TChart.Canvas
напрямую крайне нежелательно и часто не будет работать должным образом.
Диаграммы функций
Диаграммы функций - это рекомендуемый способ рисования функциональных графиков, в отличие, например, от предварительного вычисления данных функций и использования line-диаграмм. Они обеспечивают независимый от масштаба контроль плавности и скорости рисования.
Вы можете увидеть примеры функциональных серий в демо "func".
Диаграммы функций
TFuncSeries
представляет одномерную функцию, определенную событием OnCalculate
. Функция рассчитывается для каждого свойства Step
пикселя изображения, поэтому вы можете использовать его для увеличения «гладкости» или скорости рисования.
Свойство Extent
можно использовать для установки экстентов x и y с целью вычисления полного экстента диаграммы. Однако во время рисования это свойство игнорируется, и функция будет отображаться в соответствии с текущим экстентом.
Свойство DomainExclusion
позволяет исключить некоторые интервалы из функциональной области. TFuncSeries правильно рисует точки разрыва, установленные DomainExclusion
. В настоящее время DomainExclusion
можно установить только во время выполнения, вызвав процедуры AddRange
или AddPoint
. Интервалы, определенные DomainExclusion
, по умолчанию закрыты, то есть содержат конечные точки; это означает, что функция не рассчитывается в конечных точках. Если исключение домена должно содержать конечные точки (при необходимости для функции y=sqrt(x)
) вызовите AddRange
с соответствующим элементом набора TIntervalOptions=(ioOpenStart,ioOpenEnd)
в качестве необязательного третьего параметра.
Свойство DomainExclusion.Epsilon
контролирует расстояние между конечной точкой и последней нарисованной точкой (конечно, в случае открытого интервала кривая начинается непосредственно в конечной точке). Epsilon
можно настроить в тех редких случаях, когда значение по умолчанию 1E-6 не дает правильных результатов.
Диаграммы метаматических выражений
TExpressionSeries
аналогичен TFuncSeries
, но функция указана в виде строки математического выражения, например 'sin(1.23456*x)'
( свойство Expression
). Диаграмма создает экземпляр FPExpressionParser для анализа строки и вычисления значений функции. Таким образом, функции могут быть нанесены на график во время разработки.
Свойство Params
позволяет определять параметры для термина функции; в инспекторе объектов он открывает редактор коллекций, в котором каждый параметр может быть указан его именем (как используется в выражении) и его значением. Если, например, параметр f
определен со значением 1.23456
, то приведенное выше выражение также можно записать как 'sin(f*x)'
.
Аналогично TFuncSeries
, исключения доменов поддерживаются для определения областей, в которых функция не может быть рассчитана. Но в соответствии с математическими соглашениями TExpressionSeries
требует в свойстве Domain
задавать регион, в котором функция определена (дополнение к исключениям домена). Регион задается строкой, такой как 'x >= 0'
. Если существует несколько условий, они должны быть разделены двоеточием, например 'x < -1; x > 1'
. Двоеточие имеет функцию логического выражения ИЛИ. Интервал определяется как '-1 < x < 1'
. Постоянные части условий также могут быть математическими выражениями - в следующем примере точка pi/2 исключается из вычисления значений функции: 'x <> pi/2'
. Десятичные числа должны вводиться с точкой в качестве десятичного разделителя, независимо от того, как он определен в системных настройках языка операционной системы.
Диаграммы B-spline
TBSplineSeries
рисует B-сплайн с заданным свойством Degree
, используя Алгоритм Де Бора.
Сегменты сплайнов короче пикселей Step
представлены прямыми линиями.
Диаграмма Cubic spline
TCubicSplineSeries
рисует кривую данных как кубический сплайн, используя стандартный пакет FPC NumLib.
В Lazarus v2.0+ свойство SplineType
позволяет выбирать между сплайнами natural и monotone Hermite, при этом последний избегает превышения интерполяции.
Функция сплайна рассчитывается для каждого Step
пикселя изображения, поэтому вы можете использовать это свойство для увеличения «сглаживания» или скорости рисования.
Источник данных должен содержать не менее двух точек и строго увеличивать координаты X (старые версии Lazarus до версии 2.0 требуют, как минимум, 4 точки данных; для меньшего количества точек вместо сплайна рисуется многоугольник, с использованием свойства BadDataPen
>, если установлена опция csoDrawFewPoints
.)
Если значения X не упорядочены и установлена опция csoDrawUnorderedX
, сплайн будет отрисован без учета проблемных точек с использованием BadDataPen
.
Параметры csoExtrapolateLeft
и csoExtrapolateRight
позволяют задавать естественную экстраполяцию слева и справа соответственно.
Fit-диаграммы
TFitSeries
выполняет подгонку методом наименьших квадратов, используя процедуры вычисления, содержащиеся в стандартном пакете Numlib из FPC. Основным соединительным элементом является TAFitLib, который является автономным и может применяться также без TAChart.
Функция подбора выбирается через свойство FitEquation
:
fePolynomial
: y = b0 + b1x + b2x2 + … + bnxn, где значение n контроллируется свойствомParamCount
(ParamCount = n + 1
).feLinear
: y = a + bxfeExp
: y = a * ebxfePower
: y = a * xbfeCustom
: y = b0X0(x) + b1X1(x) + b2X2(x) + … + bnXn(x) где значение n контроллируется свойствомParamCount
(ParamCount = n + 1
), и Xi(x), i = 0..n, являются «базовыми функциями», которые определяются методомSetFitBasisFunc(AIndex: TFitFuncIndex; AFitFunc: TFitFunc; AFitFuncName: String)
.AIndex
- индекс i базовой функции,1..MaxInt
.AFitFuncName
- текстовое представление функции, используемой для легенды по умолчанию.AFitFunc
- адрес базовой функции Xi(x), которая имеет сигнатуруfunction(x: ArbFloat; Param: Integer): ArbFloat
сArbFloat
, являющимся общим типом данных с плавающей точкой в FPC Numlib (unit typ). Некоторые базовые функции легко доступны в модуле TAFitLib:
function FitBaseFunc_Const(x: ArbFloat; Param: Integer): ArbFloat; // константа
function FitBaseFunc_Linear(x: ArbFloat; Param: Integer): ArbFloat; // линейный член (x)
function FitBaseFunc_Square(x: ArbFloat; Param: Integer): ArbFloat; // квадратный член (x^2)
function FitBaseFunc_Cube(x: ArbFloat; Param: Integer): ArbFloat; // кубический член (x^3)
function FitBaseFunc_Poly(x: ArbFloat; Param: Integer): ArbFloat; // power term (x^Param)
function FitBaseFunc_Sin(x: ArbFloat; Param: Integer): ArbFloat; // sin(x*Param)
function FitBaseFunc_Cos(x: ArbFloat; Param: Integer): ArbFloat; // cos(x*Param)
По умолчанию параметры b0, b1, ..., a, b
варьируются в процессе подбора так, что среднее значение квадратичного отклонения между данными и подобранными кривыми было сведено к минимуму. Однако также возможно поддерживать один или несколько параметров подгонки постоянными, например, чтобы заставить подобранную прямую линию проходить через начало координат. Для этого значения постоянных параметров должны быть указаны в ';' или '|' для разграничения списка строковых значений свойства FixedParams
. Порядок значений должен соответствовать порядку подгоночных параметров. Параметры переменных можно оставить пустыми или заменить нечисловой строкой.
Пример: FixedParams='var;2'
(или короче: ';2'
) означает, что первый подходящий параметр является переменной, но второй параметр остается постоянным со значением 2; если имеется более 2 параметров, остальные также считаются переменными.
Диапазон подгонки обычно определяется экстентом диаграммы, но может быть установлен вручную через свойство FitRange
. Функция подгонки рисуется по всей оси, если только DrawFitRangeOnly=true
.
Когда подгонка завершена, ErrCode
диаграммы устанавливается так, чтобы показать, был ли расчет успешным или нет:
fitOK
: успешноfitDimError
: расчет был прерван, потому что размеры массивов данных (x, y, полоса ошибок y) не совпадают.fitMoreParamsThanValues
: расчет не удался, потому что есть больше подгоночных параметров, чем значений данных.fitNoFitParams
: расчет прерван, потому что параметры подгонки не указаны. Это может произойти случайно, если все параметры подгонки будут исправлены в свойствеFixedParams
.fitSingular
: матрица дизайна задачи подгонки оказывается (почти) единственной.fitNoBaseFunction
: для случаяFitEquation=feCustom
указано недостаточно базовых функций подгонки.
Метод ErrorMsg
создаст текст для сообщения об ошибке из текущего ErrCode
.
Событие OnFitComplete
вызывается после того, как найдено уравнение подгонки, но до начала рисования. Это хорошее место для запроса результатов процедуры подбора:
Param[AIndex]
является наиболее подходящим значением для параметра с указанным индексом,AIndex = 0..ParamCount-1
.ParamError[AIndex]
сообщает неопределенность ("standard error" (стандартная ошибка) в статистическом выражении) соответствующего параметра подгонки.- Процедура
GetConfidenceLimits(AIndex: Integer; out ALower, AUpper: Double)
возвращает диапазон междуALower
иAUpper
, в пределах которого ожидается наилучшее соответствие того, что параметр будет найден с вероятностью, указанной вConfidenceLevel
(по умолчанию:0.95
, т.е. 95%). Param_tValue[AIndex]
возвращает значение t-статистики для соответствующего параметра подгонки. Это соотношение стоимости, деленное на стандартную ошибку. Для точного параметра значение t должно быть намного больше 1.Param_pValue[AIndex]
- это вероятность того, что любое значениеt
, столь же высокое, какParam_tValue
, будет случайно получено для данных степеней свободы. Чтобы «доверять» подобранному значению с уверенностью, заданнойConfidenceLevel
, значение p должно быть меньше, чем1 - ConfidenceLevel
, по умолчанию 0,05.FitStatistics
сообщает о других статистических параметрах, полезных для проверки достоверности подобранной модели или для дальнейших статистических расчетов. Эти данные доступны как свойства или функции этого класса:N
(integer): количество точек данных, используемых для подгонки. Обратите внимание, что это может быть меньше точек данных, предоставленных источником диаграммы, поскольку он может содержать значения NaN, которые пропускаются.M
(integer): количество подгоночных параметров. Обычно это значениеParamCount
, но если определенные параметры вынуждены быть постоянными (FixedParams
), их количество вычитается.DOF
(integer): "degrees of freedom" (cтепени свободы) - это разницаN - M
, важный параметр в статистическом анализе результатов подбора.SST
: "total sum of squares" (общая сумма квадратов) - это сумма квадратов члена(y[i] - ymean)/dy[i]
по всем точкам данных. Здесьy[i]
- это значениеy
точки данных с индексомi
,dy[i]
размера ее полосы ошибок (стандартное отклонение) - или 1, если недоступно, аymean
- это среднее значениеy[i]/dy[i]
. Количество определяет общее изменение точек данных вокруг их среднего значения.SSE
: "error sum of squares" (сумма ошибок квадратов) - изменение точек данных вокруг подогнаной кривой, т.е. сумма((y[i] - ycalc(x[i])/dy[i])^2)
; здесьycalc(x[i])
- вычисленное значение подгоночной кривой в точкеx[i]
.SSR
: "regression sum of squares" (сумма квадратов регрессии) - изменение только подогнанной кривой, то есть сумма((ycalc(x[i]) - ymean)/dy[i])^2
.xBar
: среднее значение координатx
всех используемых точек данных.SSx
: изменение координатx
точек данных, то есть сумма(x[i] - xbar)^2
.VarCovar[i, j: Integer]: Double
: является элементом матрицы дисперсии-ковариации для параметров подгонки при данных индексах.R2
: "коэффициент детерминации". Это - соотношениеSSR/SSE
, и описывает, насколько сильно разброс данных объясняется подобранной кривой. Значение 1 для идеальной подгонки и 0 для абсолютной без соглашения.AdjR2
: был введен для компенсации эффекта, который обычно увеличиваетсяR2
, добавляя все больше и больше подходящих параметров.Chi2
: другое слово дляSSE
. По сути, это статистическая величина, которая минимизируется во время процедуры подбора. Данное значение является минимальным найденным значением.ReducedChi2
: этоChi2
(или:SSE
), которое нормализовано по степеням свободы, то есть изменению данных вокруг подобранной кривой на степень свободы. Должно быть "маленьким" для хорошей подгонки.ResidualStdError
: общая стандартная ошибка подгонки. Должно быть "маленьким".pValue
: (дробная) вероятность того, что остаточный разброс точек данных вокруг подобранной кривой является случайным. Должно быть высоким, на практике несколько десятков, хотя иногда значения до 0,001 по-прежнему принимаются. Если в подбор не включены никакие полосы ошибок, иногда p оказывается равным 0 или 1 - такие значения следует игнорировать.
- Процедуры
GetLowerConfidenceInterval(const Ax: Double; out AY: Double)
,GetUpperConfidenceInterval
,GetLowerPredictionInterval
иGetUpperPredictionInterval
могут быть подключены к событиюOnCalculate
TFuncSeries, чтобы построить границы нижнего и верхнего доверительных интервалов и интервалов прогнозирования вокруг подобранной кривой. Эти пределы определяют области вокруг подобранной кривой, в пределах которых можно ожидать общую подгоночную кривую (доверительный интервал) или отдельные точки данных (интервал прогнозирования) на основе вероятности, заданнойConfidenceLevel
. - Примечание: все эти статистические данные предполагают, что остаточные ошибки соответствуют нормальному распределению и что столбцы ошибок были оценены надлежащим образом.
EquationText
возвращает интерфейс IEquationText
, который позволяет построить строку, представляющую уравнение соответствия. Вы можете переопределить имена переменных x и y, числовой формат и, наконец, получить строку из функции Get
. Обратите внимание, что преобразование из IEquationText в String определено, поэтому обычно нет необходимости явно вызывать Get
.
Legend.Format
-свойство fit series поддерживает дополнительный аргумент формата ('%2:s'), указывающий на текст уравнения по умолчанию.
После изменения параметров TFitSeries
уравнение будет пересчитано на следующем отрисовке диаграммы. Чтобы немедленно пересчитать его, вызовите процедуру ExecFit
. Используйте свойство State
, чтобы проверить правильность текущего уравнения.
Диаграмма цветовых карт
TColorMapSeries
представляет собой двумерную функцию, определенную событием OnCalculate
как поле пикселей, цвет которого зависит от значения функции.
Диаграмма отображается в виде набора прямоугольников размером StepX
с помощью StepY
пикселей. Функция вызывается один раз для каждого прямоугольника.
Цветовые значения определяются одной из встроенных палитр (свойство BuiltinPalette = cmpHot, cmpCold, cmpRainbow, cmpMonochrome
). Диапазон значений, сопоставленных с цветами палитры, должен быть указан в BuiltinPaletteMax
и BuiltinPaletteMin
, иначе результаты не будут предсказуемыми.
Альтернативно, внешний ChartSource может быть назначен свойству ColorSource
, которое должно быть отсортировано. Каждая точка данных источника диаграммы интерпретируется как имеющая значение X, соответствующая значению Color. Если фактическое значение попадает между уровнями цвета, оно может быть либо линейно интерполировано (если Interpolate
равно true
), либо округлено до ближайшего уровня.
В случае, когда Legend.Multiplicity=lmPoint
, диаграмма цветовых карт будет отображать уровни цвета в Легенде.
Диаграмма цветовых карт выражения
аналогична диаграмме цветовых карт с тем отличием, что двумерная функция определяется не событием, а математическим выражением, таким как x^2+y^2
, как и в TExpressionSeries, но теперь с двумя переменными x
и y
. Переменные могут быть переименованы с помощью свойств VariableNameX
и VariableNameY
. Аналогично TExpressionSeries также можно вводить параметры (свойство Params
). Домены, однако, не поддерживаются, функция должна быть определена во всем видимом диапазоне x/y.
Источники
Данные могут попасть в график из разных источников. Они реализованы как набор компонентов, производных от TCustomChartSource
.
Чтобы назначить источник диаграмме, вы можете задать свойство Source
. Если свойство оставлено неназначенным, диаграмма будет использовать свой собственный встроенный список источников. Такие методы, как AddXY
, делегируются текущему источнику диаграммы. Обратите внимание, что список источника является единственным редактируемым источником, поэтому после назначения, например, случайного источника диаграммы для серии, вызов AddXY
вызовет исключение.
Каждый элемент данных имеет следующие поля: X
, Y
, XList
, YList
, Color
, Text
.
Отсортированные источники
Если известно, что значения X источника возрастают, возможны некоторые дополнительные оптимизации, такие как бинарный поиск. Таким образом, все источники имеют свойство IsSorted
, которое помогает определить это.
В Lazarus 2.1+ TListChartSource
можно отсортировать по нескольким критериям:
SortBy
=sbX
,sbY
,sbText
,sbColor
,sbCustom
: сортировка по значению X или Y, тексту, цвету или определенным пользователем способом соответственно. В последнем случае должен быть предоставлен обработчик для событияOnCompare
.SortIndex
: индекс значений X или Y, используемый для сортировки.SortDir
=sdAscending
,sdDescending
: сортировка в порядке возрастания или убывания.
Когда источник сортируется по чему-либо, кроме x, это влияет только на порядок отрисовки связанных рядов, и возможно, что на диаграмме ничего не изменится. Визуальный эффект заметен для
TPieSeries
потому что порядок точек данных определяет порядок срезов по кругуTBubbleSeries
когда пузырьки перекрываются. Используйте сочетаниеSortBy=sbY
,SortIndex=1
иSortDir=sdDescending
, чтобы избежать покрытия пузырьков, потому что сначала появляются большие пузырьки, а маленькие - последними.- все серии унаследованы от
TBasicPointSeries
, когдаXCount
связанного источника диаграммы равен 0: в этом случае значение X источника игнорируется и заменяется индексом точки данных. Поскольку индекс точек данных изменяется при сортировке, точки данных будут автоматически переставлены в отсортированном порядке - см. Пример sort_demo в папке demo.
Источники с множеством значений
Источники могут содержать несколько значений Y для каждого значения X. Эти значения хранятся в поле YList
исходного элемента данных. Количество значений Y определяется свойством YCount
. Обратите внимание, что первое значение Y в любом случае сохраняется в поле Y, поэтому YCount=3
означает, что значения хранятся в Y
, YList[0]
и YList[1]
.
Дополнительные значения могут использоваться в различных сериях - например, столбчатые диаграммы с накоплением или пузырьковые диаграммы.
Более того, также возможно сохранять несколько значений X для одной и той же точки данных. Это требуется для TFieldSeries
. Эти дополнительные значения X хранятся в XList
исходного элемента данных. Как и в случае со значениями Y, общее количество значений X задается свойством XCount
, которое содержит "обычное" значение X плюс длину массива XList
.
Пропуск исходных элементов
Можно указать TAChart пропустить рисование некоторых исходных элементов, не удаляя их из источника. Это может быть полезно как для оптимизации, так и для пользовательского интерфейса.
Чтобы пропустить элемент, присвойте NaN либо значению X, либо одному из значений Y. Точный эффект пропуска зависит от серии, но обычно установка X в NaN означает пропуск всего элемента, в то время как установка Y или некоторого элемента YList означает пропуск только этого значения Y, при этом все еще отрисовывая другие.
Также обратите внимание, что если вы установите NaN только для одной координаты, другая все равно будет участвовать в вычислении экстента.
В случае составных серий неясно, как следует обрабатывать отсутствующее значение, когда к нему добавляются следующие уровни. В Lazarus v2.1 + есть свойство StackedNaN
, которое можно выбрать как
snReplaceByZero
- отсутствующее значение считается нулевым; это как Excel обрабатывает этот случай.snDoNotDraw
- пропускает всю точку данных со всеми уровнями стека.
Вы можете увидеть примеры пропуска элементов в демо "nan".
Планки погрешностей
TLineSeries
, TBSplineSeries
, TCubicSplineSeries
и TFitSeries
могут отображать планки погрешностей(error bars) в каждой точке данных. Размер планок погрешностей в направлениях x
и y
определяется параметрами в свойствах XErrorBarData
и YErrorBarData
соответственно:
Kind: TChartErrorBarKind
: определяет, как интерпретируются следующие данныеebkNone
: игнорировать - планки погрешностей отображаться не будутebkConst
: все точки данных имеют одинаковую планку погрешности, заданнуюValuePlus
иValueMinus
.ebkPercent
: значенияValuePlus
иValueMinus
понимаются как процент от значений данных.ebkChartSource
: каждая точка данных может иметь отдельную планку погрешности. Длина планок погрешностей сохраняется в XList или YList источника многозначной диаграммы. Индекс среди всех значений x и y задаетсяIndexPlus
иIndexMinus
для положительной и отрицательной планки погрешности соответственно.
ValuePlus
иValueMinus
: длина столбцов положительных и отрицательных погрешностей соответственно. В зависимости от настройкиKind
предполагается, что значение является постоянным для всех точек данных (Kind = ebkConst
, единицы оси) или в процентах от значения точки данных (Kind = ebkPercent
). Оба значения должны быть положительными числами, за исключениемValueMinus = -1
, который указывает, что отрицательная планка погрешности должна быть равна положительной планке погрешности.IndexPlus
иIndexMinus
используются, когдаKind
равенebkChartSource
и указывают индекс x или y в многозначном chartsource, из которого можно получить длину планки погрешности для отдельных точек данных. Предположим, что источник диаграммы содержит два значения x (XCount = 2
) иXErrorBarData.ValuePlus
равно 1, тогда второе значение x (хранящееся вXList[0]
) используется для положительной длины планки погрешности. ЕслиIndexMinus
равно -1, то предполагается, что длина отрицательной планки погрешности равна длине положительной планки погрешности без необходимости предоставления явного значения в источнике диаграммы.
y
для других целей, кроме отдельных планок погрешностей, не рекомендуется в этом контексте, поскольку настоящая реализация может отображать планки погрешности только для значения y
с индексом 0.Каждый тип серии, поддерживающий планки погрешностей, имеет дополнительные свойства XErrorBars
и YErrorBars
, которые определяют, как планки погрешностей будут отображаться:
Visible
можно использовать для отключения планок погрешностей, даже если их размер указан в источнике диаграммы.Width
- это длина перекладины, нарисованной в конце планки погрешностей. Значение по умолчанию -1 означает, что его длина будет равна соответствующему размеруPointer
серии.Pen
определяет параметр пера, используемый для рисования планок погрешностей. Обычно дляPen.Color
устанавливается цвет серии.
Список источников
TListChartSource
- это базовый источник диаграммы, хранящий данные диаграммы внутри себя. Таким образом, вы можете использовать функции Add
и Delete
для изменения исходных данных.
Свойство Item
возвращает указатель непосредственно на базовое хранилище, поэтому вы можете напрямую изменять поля элемента. Однако это не приведет к автоматическому обновлению диаграммы, а также сделает недействительным некоторое внутреннее состояние списка источника.
Рекомендуется:
- Чтобы изменить отдельный элемент, используйте процедуры Set{Color|Text|XValue|YValue|YList}.
- Чтобы изменить многие элементы в чувствительном ко времени коде, вызовите
BeginUpdate
, затем измените элементы напрямую, потом вызовитеEndUpdate
.
Источник также имеет свойство DataPoints
, позволяющее задавать данные во время разработки. Это свойство - TStringList, где каждая строка представляет точку данных. Строка состоит из значений X, Y, необязательных значений YList, Color и Text, разделенных символом |
(вертикальная черта). Обратите внимание, что свойство DataPoints
предназначено в первую очередь для создания образцов кода и демок. Оно очень неэффективно, и вы не должны использовать его для добавления точек данных из кода.
Вы можете управлять сортировкой значений X, задав свойство Sorted
. Обратите внимание, когда для параметра Sorted
установлено значение true
, список источника сортирует данные и сохраняет их отсортированными после вставки новых точек. Если вставленные точки не отсортированы, это может привести к квадратичному времени выполнения. Вы должны либо установить для Sorted
значение true
только после вставки, либо предварительно отсортировать данные, чтобы избежать этого.
Случайный источник
Источник TRandomChartSource
генерирует случайные данные в заданном диапазоне и предназначен в основном для использования в демках.
Вы также можете использовать его как замену времени разработки для вашего фактического источника данных.
Это позволит вам видеть и изменять внешний вид вашей диаграммы без необходимости запускать приложение.
Каждый случайный источник использует свой собственный независимый генератор случайных чисел, чтобы гарантировать стабильность его значений.
Предопределенный пользователем источник
Этот источник можно использовать, если у вас уже есть данные в памяти, но в формате отличается от элементов данных, используемых в TAChart. С помощью источника, определяемого пользователем, вы можете напрямую обращаться к своим данным, вместо того, чтобы сначала перемещать их все в список источника. В некоторых случаях это может улучшить производительность или снизить потребление памяти. Конечно, вы также можете генерировать, фильтровать или изменять данные с помощью пользовательского источника.
Количество элементов данных в источнике определяется свойством PointsNumber
.
Сами элементы должны быть возвращены обработчиком события OnGetChartDataItem
.
Вы должны вызвать метод Reset
, чтобы уведомить диаграмму об изменениях данных.
(Другие источники обнаруживают изменения и автоматически отправляют уведомление).
Обратите внимание: если для свойства Sorted
установлено значение true
, это ответственность
обработчика событий для предоставления фактически отсортированных данных.
Источник из базы данных
TDbChartSource
берет данные прямо из базы данных.
Он содержится в отдельном модуле, чтобы не вводить зависимость компонента с учетом базы данных.
в каждый проект с помощью TAChart.
Следующие свойства содержат имена полей базы данных для полей элементов данных:
Свойство | Метод доступа |
---|---|
FieldX |
AsFloat (или AsDateTime, если задана опция dcsoDateTimeX) |
FieldY |
AsFloat (или AsDateTime, если задана опция dcsoDateTimeY) |
FieldColor |
AsInteger |
FieldText |
AsString |
Если свойство FieldX
пусто, вместо него используется RecNo.
NULL
значения кода в полях координат переводятся в NaNs.
Чтобы получить источник со множеством значений, задайте для свойства FieldY
список имен полей, разделенных запятыми.
Обратите внимание, что YCount
будет задан автоматически - попытка задать его вручную вызовет исключение.
Вычисляемый источник
TCalculatedChartSource
- это источник, используемый для управления данными, взятыми из источника Origin
.
Этот источник выполняет преобразования в следующем порядке:
- Изменение порядка Y - значения Y источника со множественными значениями могут быть дублированы, удалены или заменены в соответствии со свойством
ReorderYList
, которое представляет собой разделенный запятыми список исходных индексов значений Y. Шаг пропускается, еслиReorderYList
пуст. - Накопление - заменяется значения Y каждого элемента функцией соседних значений.
- Процент - заменяется каждое значение Y на процент от общего количества всех значений Y для этого элемента. Полезно для рисования "столбчатых диаграмм" и диаграмм с областями. Шаг пропускается, если свойство
Percentage
имеет значениеfalse
.
Накопление контролируется несколькими свойствами:
AccumulationRange
контролирует количество элементов для накопления, считая текущий элемент,
поэтому AccumulationRange = 1
отключает накопление.
AccumulationRange = 0
интерпретируется как «бесконечный» диапазон, т.е. запрос на накопление по всем
имеющимся данным. Это в основном полезно в сочетании с методом camSum
для создания
совокупных сумм.
Обратите внимание, что фактическое количество элементов может быть меньше для точек около начала или конца источника.
AccumulationDirection
:
- cadBackward - использовать предыдущие значения из источника,
- cadForward - использовать следующие значения из источника,
- cadCenter - используйте предыдущие и следующие значения для общего числа до
2 * AccumulationRange - 1
.
AccumulationMethod
:
- camNone - пропустить шаг накопления,
- camSum - сумма последнего элемента
AccumulationRange
, - camAverage - среднее значение последнего элемента
AccumulationRange
, - camDerivative - производная конечных разностей, рассчитанная с использованием последнего элемента
AccumulationRange
. Обратите внимание, что метод расчета предполагает эквидистантные значения X и может потерять точность, если расстояние X существенно меняется. - camSmoothDerivative - сглаженная производная конечных разностей, более устойчивая к случайным ошибкам измерения в данных.
Интервальный источник
TIntervalChartSource
может предоставить произвольное количество точек в заданном интервале, контролируемом различными свойствами источника.
Этот источник является встроенным по умолчанию источником для меток осей.
Если вы хотите установить одинаковые параметры интервала осей для нескольких осей,
Вы можете назначить один компонент TIntervalChartSource
для Marks.Source
каждой из этих осей.
Источник интервала даты и времени
TDateTimeIntervalChartSource
похож на TIntervalChartSource
, но предоставляет метки в формате значения даты/времени. Этот источник автоматически выбирает подходящий календарный интервал (например, неделя или час) в зависимости от масштаба оси.
Обратите внимание, что значения X предоставленных элементов данных - это значения TDateTime
и значения Label
содержат отформатированные строки даты и времени. Если вы хотите использовать TDateTimeIntervalChartSource
в качестве источника меток оси, вам, вероятно, следует установить свойства Marks.Format
или Marks.Style
, чтобы использовать предоставленные метки.
Если задано свойство DateTimeFormat
, оно используется для форматирования всех меток.
Форматирование выполняется стандартной SysUtils.FormatDateTime.
Если DateTimeFormat
пуст, формат выбирается автоматически в зависимости от масштаба.
TDateTimeIntervalChartSource
определяется в модуле TAIntervalSources.
Примечания по оптимизации источников
API первичного источника данных допускает произвольный доступ. Тем не менее, многие источники, в частности рандомные, из базы данных и вычисляемые, могут проявлять квадратичное или худшее поведение при случайном доступе. Сам TAChart заботится об использовании только последовательного доступа (хотя может потребоваться несколько проходов). Источники оптимизируют последовательный доступ с помощью внутреннего состояния. Код пользователя должен быть аккуратен, чтобы не сбросить это состояние во время рисования диаграммы из обработчиков событий или кода пользовательской серии.
Заметным исключением является списочный источник, который гарантированно обеспечивает быстрый произвольный доступ. Его можно использовать для кеширования медленных источников с помощью процедуры CopyFrom
.
Также обратите внимание, что указатель, возвращаемый функцией GetItem
, может указывать на внутренний буфер, который будет перезаписан следующим вызовом GetItem
. Опять же, списочный источник не имеет этого ограничения.
Координаты и оси
- Координаты оси (известные в некоторых других приложениях как координаты объекта) — это «сырые» значения координат, полученные из данных. Как следует из названия, координаты оси интерпретируются в терминах конкретной оси — одно и то же значение координаты может иметь разное значение в зависимости от оси, к которой оно применяется.
- Координаты графика (также известные как мировые координаты) преобразуются из координат оси с использованием преобразования оси, например логарифмического масштаба. Координаты графика общие для всех объектов на графике.
- Координаты изображения (также известные как координаты экрана) преобразуются из координат графика на основе области просмотра диаграммы. Это преобразование всегда является линейным, и на него могут влиять такие инструменты диаграммы, как масштабирование и панорамирование.
- Координаты устройства обычно равны координатам экрана, но могут быть скорректированы в соответствии с бэкендом чертежа, чтобы приспособиться к различным физическим разрешениям (значениям DPI). См., например, отрисовщик принтера.
Вы можете добавить или удалить произвольное количество осей, отредактировав свойство AxisList
. По умолчанию диаграмма имеет две оси: одну горизонтальную и одну вертикальную. Они доступны через свойства BottomAxis
и LeftAxis
. Обратите внимание, что эти свойства являются псевдонимами для кода AxisList[0]
и AxisList[1]
, поэтому, если вы удалите эти оси по умолчанию, доступ к BottomAxis
и LeftAxis
вернет nil
.
Визуально ось состоит из осевой линии (нарисованной AxisPen
), линий сетки (нарисованной GridPen
), делений, меток и стрелки.
Каждая ось рисуется внутри собственного прямоугольника, определяемого размером меток и делений. Назначив нескольким осям один и тот же положительный Group
номер, вы можете сделать так, чтобы они разделяли одну и ту же прямоугольную область. Сгруппированные оси можно использовать для создания «панелей», когда несколько рядов рисуются на разных участках одного и того же графика.
Оси с одинаковым выравниванием, но разными группами, укладываются рядом друг с другом. Вы можете использовать свойство Margin
для управления расстоянием между такими осями.
Преобразования осей
Преобразования осей сгруппированы в компоненте TChartAxisTransformations
. Он содержит список преобразований, которые применяются в указанном порядке. (Например, выполнение масштабирования до и после логарифмирования даст разные результаты).
Чтобы преобразования возымели эффект, следует:
- Убедиться, что свойство
Enabled
имеет значение true для всех преобразований. - Назначить компонент преобразований свойству
Transformations
хотя бы одной оси. - Назначить свойства
AxisIndexX
и/илиAxisIndexY
ряда соответствующему индексу оси.
Обратите внимание, что по умолчанию AxisIndexX
иcode>AxisIndexY имеют специальное значение -1, что означает «игнорировать преобразования осей». Также обратите внимание, что если вы добавите или удалите оси, индексы могут измениться. Вы можете повернуть серию, назначив AxisIndexX
вертикальной оси и AxisIndexY
горизонтальной оси.
Линейное и логарифмическое преобразование
Это простые арифметические преобразования.
Трансформация с автоматическим масштабированием
Чтобы отобразить несколько серий с независимым масштабированием, назначьте их двум или более осям и примените TAutoScaleAxisTransform
к каждой оси. См. демку "axistransf", страница "Linear", флажок "Auto scale".
Используя свойства MinValue
и MaxValue
, вы можете управлять координатами на графике автоматически масштабируемого ряда. Например, задав одному преобразованию диапазон от 0 до 1, а другому — диапазон от 1 до 2, вы ограничите все ряды, использующие первое преобразование, верхней половиной диаграммы, а все ряды, использующие второе преобразование в нижнюю половину (при условии, что не осталось неназначенных рядов).
Совокупное преобразование нормального распределения
Используйте TCumulNormDistrAxisTransform
, чтобы установить кумулятивное нормальное распределение как преобразование оси. Это может быть полезно при составлении статистических графиков.
Обратите внимание, что результат этого преобразования находится в диапазоне от 0 до 1. Рекомендуется соответствующим образом ограничить диапазон осей.
См. пример на странице «Нормальное распределение» демки «axistransf».
Пользовательское преобразование
Вы можете создать свою собственную трансформацию либо путем наследования от TAxisTransform
, или, если вы предпочитаете «визуальное» программирование, используйте TUserDefinedAxisTransform
.
В любом случае есть два основных требования:
- функции
AxisToGraph
иGraphToAxis
должны быть определены везде в диапазоне данных и обратны друг другу (например, теперь избегайте только деления, а также умножения на ноль). - Функции должны быть монотонными.
Оси даты и времени
Использование значений даты/времени для меток оси является распространенным требованием. Правильный способ сделать это зависит от точного характера ваших данных даты/времени:
- Если данные являются актуальными значениями
TDateTime
, используйте его как координату X в пунктах, назначьтеTDateTimeIntervalChartSource
Marks.Source
соответствующей оси, аMarks.Style
измените наsmsLabel
.TDateTimeIntervalChartSource
обеспечивает автоматическую маркировку в зависимости от масштаба в широком диапазоне -- от столетий до миллисекунд. - Если данные представлены в физических единицах, но вне диапазона значений
TDateTime
, таких как астрономические или микроэлектронные тайминги, используйте их как обычную координату X с пользовательскимMarks.Format
. - Если данные представлены в календарных единицах, таких как месяцы и годы, что характерно для финансовых данных, у вас есть несколько вариантов:
- Если единицы даты «равноудалены» при интерпретации как числа (например, простые числа года), назначьте один и тот же источник данных как для серий, так и для меток осей, а затем используйте пользовательский
Marks.Format
, событиеAxis.OnMarkToText
или полеText
элементов данных для форматирования дат в соответствии с вашими требованиями. - Если единицы даты не «равноудалены» (например, числа в формате ГГГГММ или даже строки-даты), вместо этого используйте суррогатную координату X (обычно просто точечный индекс) и отображайте даты, используя методы, описанные выше.
- Предварительно преобразуйте координаты в значения
TDateTime
, затем используйтеTDateTimeIntervalChartSource
, как описано выше.
- Если единицы даты «равноудалены» при интерпретации как числа (например, простые числа года), назначьте один и тот же источник данных как для серий, так и для меток осей, а затем используйте пользовательский
Диапазоны осей
Диапазон оси измеряется в осевых единицах и определяет протяженность ряда, прикрепленного к этой оси.
Обычно диапазон осей равен объединению всех экстентов серии, но его можно переопределить с помощью свойства Range
.
Метки осей отображаются внутри диапазона меток осей, который определяется как пересечение:
- Логический экстент (преобразованный в координаты оси)
- Суммарный экстент всех рядов данных этой оси, если
Marks.AtDataOnly = true
- Свойство
Marks.Range
.
Интервалы осей
Метки осей располагаются вдоль оси через равные промежутки, выбранные графиком.
На выбор интервалов можно повлиять с помощью свойства Intervals
. Это свойство имеет несколько подсвойств, которые применяются в следующем порядке:
- Свойство
Options
содержит набор флагов, управляющих использованием других параметров. Если флаг не установлен, соответствующий параметр игнорируется. NiceSteps
— это строка, содержащая последовательность «множителей шага» — значений с плавающей запятой в диапазоне от 0 до 1, исключая 0. Если это свойство применяется, шаг оси будет равен степени десяти, умноженной на одно из предоставленных значений. Если можно использовать несколько множителей, будет выбран крайний левый. Множители разделяются вертикальной чертой (|).- Если
NiceSteps
игнорируется или TAChart не может найти подходящий шаг, диапазон оси будет разделен на равные интервалы независимо от количества знаков после запятой в представлении значений меток. В этом случае рекомендуется уменьшить количество видимых цифр вMarks.Format
. - свойства
MinLength
иMaxLength
устанавливают пределы длины интервала «в единицах изображения» (обычно в пикселях). - Свойство
Count
— желаемое количество меток оси. Среди всех шагов оценки, прошедших предыдущие тесты, TChart выбирает тот, который дает количество оценок, ближайшее кCount
. Если свойствоCount
игнорируется или есть несколько шагов с одинаковым количеством меток, выбирается самый длинный шаг. - Свойство
Tolerance
устанавливает максимальное расстояние «в единицах изображения», на которое может быть перемещена метка, чтобы уменьшить длину ее десятичного представления. Это помогает избежать большого количества бессмысленных цифр в заголовках меток, когда предыдущие шаги по какой-то причине не привели к созданию «хороших» меток. Обратите внимание, что на этом этапе игнорируются все предыдущие ограничения, поэтому большие значенияTolerance
могут привести к значительным искажениям. Часто бывает достаточно установкиTolerance = 1
.
Обратите внимание, что если вы устанавливаете источник диаграммы вручную, свойство Intervals
может применяться только частично или не применяться вовсе. Например, список источника не может гарантировать максимальную длину интервала, так как он имеет только конечное число точек. См. также интервальный источник диаграммы.
Положение оси
По умолчанию ось выравнивается по стороне диаграммы, соответствующей свойству Alignment
.
Вы можете позиционировать ось по-разному, задав свойства Position
и PositionUnits
.
Допускаются следующие значения свойства PositionUnits
:
cuPercent
-- процент отсечения прямоугольника.cuGraph
-- абсолютная позиция в координатах графика.cuPixels
-- позиция в единицах экрана относительно координат по умолчанию.
Примечание 1: Если положение оси отличается от значения по умолчанию (Position = 0
и PositionUnits = cuPercent
), он будет исключен из расчета полей, поэтому будет казаться, что он перекрывает серию.
Примечание 2: Alignment
влияет не только на положение самой оси, но и на соответствующие метки. Таким образом, если две оси имеют Position = 50
и PositionUnits = cuPercent
, но одна имеет Alignment = calLeft
, а другая Alignment = calRight
, они будут отображать общую линию оси с метками на разных стороны.
См. пример на странице "Position" демку "axis".
Названия осей
Если свойство TextFormat переключено на tfHTML, то HTML-объекты и теги могут быть встроены для специального форматирования заголовков осей, таких как подстрочные/надстрочные индексы или греческие символы. Подробнее см. HTML.
Размер LabelSize
Начиная с Lazarus v1.4 оси диаграммы имеют новое свойство LabelSize
, которое, если оно отличается от 0
, переопределяет автоматический расчет пространства, необходимого для меток осей. LabelSize
приблизительно определяет пиксели между линией оси и заголовком оси, независимо от размера меток оси. Эту функцию можно использовать для выравнивания линий осей нескольких диаграмм, которые расположены друг над другом или рядом.
См. демку «axisalign» и графическое объяснение для примера.
LabelSize
слишком маленькое, метки осей могут доходить до заголовка оси или даже обрезаться на границе диаграммы.Экстенты и поля
Экстенты
Экстент диаграммы представляет собой прямоугольник в координатах графа.
TChart определяет несколько экстентов:
- Full extent (полный) -- обычно определяется автоматически как область, охватывающая все данные из рядов и диапазонов осей. Возвращается функцией
GetFullExtent
. - Fixed extent(фиксированный) -- определяется свойством
TChart.Extent
. Может частично или полностью переопределить расчет полного экстента. LogicalExtent
-- запрошенный пользователем экстент для отображения на изображении диаграммы. Запись в это свойство является официальным способом изменения экстента диаграммы с помощью внешнего кода. Например,LogicalExtent := GetFullExtent
(почти) эквивалентен вызову процедурыZoomFull
.CurrentExtent
-- экстент, фактически отображаемый пользователю. Может отличаться отLogicalExtent
из-за необходимости резервирования места для ряда метки, внутренней диаграммы поля и т.д.
Значение минимального экстента не может быть больше значения максимального экстента. При попытке установить такие значения будет сгенерировано исключение. Для предотвращения исключений можно использовать процедуру .Extent.FixTo(aBounds: TDoubleRect)
для установки логических экстентов. Значения в TDoubleRect
упорядочены следующим образом: [xmin, ymin, xmax, ymax].
Чтобы инвертировать экстенты, свойство Inverted
оси (левой, нижней и т.д.) должно быть установлено в True
.
Важно: установка логических экстентов будет работать должным образом, только если для всех Margins
диаграммы установлено значение 0 (значение по умолчанию — 4), а для параметра Series.Marks.AutoMargins
для всех рядов диаграммы установлено значение False
(по умолчанию — True
). В противном случае запрошенный экстент будет увеличен, чтобы включить в него также Margins
диаграммы и Marks
серии.
Extent limits
By default, TAChart allows arbitrary extents. However, for both usability and speed reasons it may be desirable to limit extent size. For example, setting the lower bound of the size may disallow extreme zoom levels, while setting the upper bound may force the user to only see a part of the very long series at any given time.
The extent can be limited with the ExtentSizeLimit
property.
Sub-properties MinX
, MinY
, UseMinX
and UseMinY
control
the lower bounds of the extent, while
sub-properties MaxX
, MaxY
, UseMaxX
and UseMaxY
control
the upper bounds.
Extent limits are expressed in graph units.
Setting Proportional = true
will enforce the current extent to have the shape of the plot area.
This may be useful for cartographic or some math plots which require the same scale on both axes.
Linked extents
Using the TChartExtentLink
component, you can ensure that the logical extents of several charts
enumerated by the LinkedCharts
property always stay the same. In Laz 2.1+ the component was extended to provide an additional property AlignSides
which adjusts the LabelSize
properties of aligned charts such that the corresponding sides of the plot area are aligned, too.
This is useful for simulating multi-pane chart layouts. See "panes" demo for an example.
Поля
Margin is a distance reserved around the edges of rectangular region. Margins are measured in image units (usually pixels). The chart itself has two kinds of margins:
- Internal (
Margins
property) -- applied after axis drawing. Are also influenced by series marks and series themselves. - External (
MarginsExternal
property) -- applied before axis drawing. Are also influenced by axis marks and arrows.
Other chart elements, such as legend, title, footer and labels, have margins, too.
Optimization notes
Calculation of CurrentExtent
and actual margins is a non-trivial iterative process (see TChart.PrepareAxis
code for details).
Although usually fast, in complex cases it can require multiple passes through chart sources.
Графическое объяснение
Tools
Chart tools define how the chart reacts to various user actions, primarily mouse movements and clicks. You can see examples of tools usage in the "tools" or "barseriestools" demos.
Tools are grouped in a TChartToolset
component,
which should be assigned to the chart's Toolset
property.
The same toolset can be used in several charts.
If Toolset
is unassigned, for compatibility reasons a built-in toolset consisting of
zoom drag and pan drag tools is used; these builtin tools can be turned off individually by setting the chart properties AllowZoom
and/or AllowPanning
to false
, respectively (the latter is available only after Lazarus v2.2+).
In each user action, tools in the toolset are processed in order, and for each tool:
- If
Enabled=false
, the tool is ignored. - If
Shift
is not equal to the current shift state, the tool is ignored. - Tool is requested to process the action.
- If the tool signals that the action is handled, processing is stopped, otherwise it continues to the next tool. This way, tools with the same
Shift
value may be differentiated based on special activation conditions. For example, some drag tools may be configured to not activate on a simple click, leaving the click event available for other actions. - Finally, if no suitable tool is found, the chart's event handler is called. Note that this means that chart event handlers will only work with all tools disabled. Generally it is recommended to use tools for interactivity, chart events are left mostly for compatibility.
In your application you can create, for example, a toolbar with each button enabling the corresponding tool in the toolset and disabling all others.
Alternatively, by assigning different Shift
values, you can enable several tools at once.
Some tools publish the EscapeCancels
property which, if set to true
, cancels the tool operation if the user pressed the ESC key.
Keyboard handling in tools
Besides mouse events, some tools may react on key presses -- for example, crosshair tool with
Shift = [ssCtrl]
will display crosshairs when the CTRL key is pressed, without mouse buttons.
Unfortunately, the chart must be focused to receive keyboard events.
This means that after the user interacted with other controls on the same form, the chart stops reacting on keyboard-only events.
To prevent this, you can either call the Chart.SetFocus
method, or set Chart.AutoFocus = true
,
which will make a chart grab the focus when the mouse moves over it.
Drawing mode
Some tools, such as zoom drag or crosshair, display moving shapes over the chart with the mouse movement.
There are two ways to display those shapes: either simply draw them over the chart, fully redrawing the chart
upon each mouse movement, or use pmXor
pen mode to draw and erase the shape directly from
the MouseMove
event handler.
The former method allows to use arbitrary pen color and style, but the latter is much more efficient.
Additionally, some widgetsets ignore all drawing outside the Paint
event, in such a case the latter method will not work at all.
The display method is controlled by the DrawingMode
property with the following values:
tdmXor
-- use XOR method;tdmNormal
-- use full chart redraw;tdmDefault
-- use XOR method on widgetsets where it is known to work (Windows and Gtk) and full redraw on others.
Extent tools
Extent tools modify the chart's logical extent.
Zooming tools can be animated by setting AnimationSteps
to a value greater then 1
and specifying an appropriate AnimationInterval
in milliseconds.
In the zooming tools, adapt the LimitToExtent
property to restrict zooming to the chart's full extent on all or some directions. The same property is available also in the panning tools for the corresponding purpose when the viewport is panned.
Zoom drag tool
TZoomDragTool
allows the user to zoom in by drawing a rectangle with the mouse.
The rectangle then becomes the new logical extent.
Restoration of the zooming to the full extent can be achieved by several actions,
controlled by the RestoreExtentOn
property:
zreDragTopLeft
,zreDragTopRight
,zreDragBottomLeft
,zreDragBottomRight
-- dragging in the specified direction,zreClick
-- clicking without dragging,zreDifferentDrag
-- dragging in a direction different from the one used to zoom in.
By default, RestoreExtentOn = [zreClick, zreDragTopLeft, zreDragTopRight, zreDragBottomLeft]
which means
that the full extent is restored either by clicking or by drawing a rectangle in any direction except from top-left to bottom-right.
To get a behavior compatible with earlier versions of Delphi's TeeChart, specify RestoreExtentOn = [zreDragTopLeft, zreDragTopRight, zreDragBottomLeft]
.
To get a behavior compatible with newer versions of TeeChart, specify RestoreExtentOn = [zreDifferentDrag]
.
The enumerated property RatioLimit
((zrlNone, zrlProportional, zrlFixedX, zrlFixedY
) lets you restrict zooming to one of the coordinates, or makes the zooming process keep the original proportions.
Zoom click tool
TZoomClickTool
allows the user to zoom in or out by clicking on the chart with the mouse.
ZoomFactor
is the scaling multiplier applied by the tool where factors below 1 represent "zoom out", and factors above represent "zoom in".
ZoomRatio
allows to create a non-proportional zooming effect by specifiying the ratio of X to Y scale. In other words, the X zoom factor is given by the property ZoomFactor
, the Y zoom factor is the product ZoomFactor*ZoomRatio
.
- In particular, to zoom only horizontally, the Y zoom factor must be 1, i.e.
ZoomFactor*ZoomRatio = 1
orZoomRatio = 1/ZoomFactor
. For example, when yourZoomFactor
for the X axis is 1.1, thenZoomRatio
must be 1/1.1 = 0.909. - Similarly, to zoom only vertically, the X factor must be 1, i.e.
ZoomFactor = 1
, and you can useZoomRatio
alone to determine the Y zoom factor. - And finally, in the normal case, when X and Y should zoom by the same ratio, keep
ZoomRatio
at 1 and determine the overall zoom factor by theZoomFactor
alone.
If FixedPoint
is true, the location of the mouse click is used as a fixed point for zooming, otherwise the chart image center is used instead.
Zoom mouse-wheel tool
TZoomMouseWheelTool
allows the user to zoom in and out with the mouse wheel.
Its properties are identical to the zoom click tool.
The chart is scaled by ZoomFactor
when the user scrolls the mouse wheel up,
and by 1/ZoomFactor
when the user scrolls the mouse wheel down.
Pan drag tool
TPanDragTool
allows the user to move the logical extent by dragging the mouse in the directions
indicated by the Directions
property.
Use the MinDragRadius
property to distinguish dragging from clicking.
Pan click tool
TPanClickTool
allows the user to move the logical extent by clicking inside a range of
Margins
pixels from the corresponding border of the chart image.
The panning offset is determined by the distance from the edge of the chart (the nearer to
the edge, the greater).
Setting Interval
in milliseconds will allow to continue panning with the given
interval until the mouse button is up.
Pan mouse wheel tool
TPanMouseWheelTool
allows the user to move the logical extent by scrolling the mouse wheel.
The extent is moved in WheelUpDirection
when the wheel is scrolled up
and in the opposite direction when the wheel is scrolled down.
The movement speed is controlled by Step
property.
Data tools
Data tools are linked to specific data series via the AffectedSeries
property,
which is a string of comma-separated series indexes.
Note that indexes may change if you add or remove series.
Having AffectedSeries
empty means that the tools operate on every series in the chart.
When a data tool is activated, it determines the nearest point of the affected series
which is located inside of the GrabRadius
(in pixels).
Using the set Targets: TNearestPointTargets
it can be controlled which part of a complex series must be hit:
nptPoint
: The tool must hit the data point at (x, y).nptXList
: If the series' source has several x values the tool must hit any of the values in the XList.nptYList
: If the series' source has several y values the tool must hit any of the values in the YList.nptCustom
: Meant for special effects depending on the series. In case of a bar series, for example, the function GetNearestPoint is overridden to accept hits inside series bars if this option is set.
All options are on by default. For further control, most series have the same set of Targets, named ToolTargets. An option must be included in the targets of both tool and series to be active. This way tools can be shared with series reacting differently on each option. See "barseriestools" demo as an example.
For large series, the efficiency can be improved by using a sorted source, a small GrabRadius
and a DistanceMode<>cdmOnlyY
.
Data point drag tool
TDataPointDragTool
allows the user to change data values by dragging the data point.
Requires the series' data source to be a list source.
You can use the OnDrag
and OnDragStart
events to limit drag direction or grab area.
See "dragdrop" demo for an example.
Data point click tool
TDataPointClickTool
allows you to assign an OnPointClick
event handler,
which will be called when the user clicks on the data point.
Data point hint tool
TDataPointHintTool
displays a hint when the user moves the mouse over the data point.
The hint is either equal to the point label (if UseDefaultHintText=true
) or
determined by calling the OnHint
event handler.
By default, this tool displays a separate hint window, independent from the application hint.
To use a single hint window per application, you may set UseApplicationHint=true
.
Note that the application-level hint does not work in combination with modifier keys
and mouse buttons, so the hint is displayed only if no buttons are pressed
(i.e. Shift
property must be empty when UseApplicationHint=true
).
Data point crosshair tool
TDataPointCrosshairTool
displays a cross-hair centered on the data point. It replaces the "reticule" found in older versions of TAChart.
Data point distance tool
TDataPointDistanceTool
allows to measure and display a distance between two points on the chart.
Chart element tools
Axis click tool
This tool fires an event OnClick
when the user clicks on an axis or its title. The event has the clicked axis and a set of TAxisHitTest
elements as parameters:
ahtTitle
: click on the axis titleahtLine
: click on the axis line (allowed tolerance defined by the tool'sGrabRadius
or the axis'TickLength
andInnerTickLength
whichever is greater).ahtLabels
: click into the label area of the axis. It is not distinguished whether a label is clicked or the empty space between the labels.ahtAxisStart
: the click on the line or label area occured in the first quarter of the axis lengthahtAxisCenter
: the click on the line or label area occured in the center part (two quarters) of the axis lengthahtAxisEnd
: the click on the line or label area occured in the last quarter of the axis length.
An OnClick
event is created when the user clicks on the title or footer of a chart. The event has the clicked title/footer as parameter.
Legend click tool
Generates an OnClick
event when a click on the chart's legend has occured. The event has the legend as a parameter.
User defined tool
To add your own tool, either inherit from TUserDefinedTool
or use it directly,
assigning one or more On{After,Before}{KeyDown,KeyUp,MouseDown,MouseMove,MouseUp,MouseWheelDown,MouseWheelUp} event handlers.
Call the Handled
method of the tool to indicate that no further processing of the event should be done.
Decorative elements
Chart title and footer are multi-line texts appearing above and below the chart correspondingly. They support various rotations and alignments.
HTML
If the Lazarus version is 1.8 or newer then html entities and some html tags can be embedded into the title/footer texts for a variety of additional formatting options. This feature is turned on by switching the property TextFormat to tfHTML. In addition to header/footer texts it is available also for axis captions, axis marks, series marks and legend texts/series titles.
- Non-standard charcters can be embedded using the corresponding html entities, i.e. as codes beginning with an ampersand (&), a standardized appreviation of the character name (or its hex or decimal unicode value), and ending with a semicolon (;). A list of all html entities can be found at http://unicode.e-workers.de/entities.php.
Example: The text sin 2α = 2 sin α cos α is displayed as "sin 2α = 2 sin α cos α" - <sub>...</sub> displays the enclosed text as subscript.
Example: H<sub>2</sub>O is shown in the chart as "H2O" - <sup>...</sup> displays the enclosed text as superscript.
Example: cm<sup>2</sup> is shown in the chart as "cm2" - <b>...</b> displays the enclosed text with bold type face.
Likewise, the tags <i>...</i>, <u>...</u>, <s>...;</s> can be used to format portions of the text as italic, underlined, andstrike-out
Example: Plot of <b>x</b> <i>vs.</i> <b>y</b> is shown in the chart as "Plot of x vs. y" - The <font>...</font> tags can be used to modify the font of the enclosed text:
- Text color: The embedded This text is <font color="red">RED</font> displays the enclosed text in red color, i.e. like "This text is RED". Specify the color by the most typical color names or by the html hex color codes of rgb values, in the format #rrggbb or #rgb where r, g, b are hex bytes for the red, green and blue color components. The three-digit codes #rgb are equivalent to the six-digit codes #rrggbb where both digits of the same component are equal.
- The font name can be specified by the name attribute.
- The font size is controlled by the size attribute. It can take the values "x-small", "small", "medium", "large", "x-large", "xx-large" for font sizes 7, 10, 12, 14, 18, 24pt, respectively. Alternatively, the point or pixel size can be specified directly if "pt" or "px", respectively, is appended.
- Example: This code adds a two-line footer in which the 2nd line is in blue, 8-pt, underlined Times New Roman:
Chart.Foot.Text.Clear;
Chart.Foot.Text.Add('Reference:');
Chart.Font.Text.Add('<font name="Times New Roman" size="8pt" color="blue"><u>www.freepascal.org/</u></font>');
Предупреждение: It is not recommended to switch font name and font size within the same line because TAChart drawers cannot exactly align the base line of characters in different fonts and font sizes
The demo application in folder demo/html of the Lazarus installation heavily makes use of embedded HTML codes.
Легенда
Chart legend is a table with each item containing an icon and a text line.
Grid lines may be controlled by GridHorizontal
and GridVertical
properties.
Legend supports various alignments and can be located inside the chart or
on the sidebar. Legend can be displayed in two or more columns
by setting ColumnCount
property.
Setting ColumnCount
to a very large value effectively creates "horizontal" legend.
Legend items are generated based on chart series which have both
Active
and ShowInLegend
set to true.
Depending on Legend.Multiplicity
series can produce a single
item or one item per point.
Legend items can be grouped together under sub-headers.
Sub-headers are taken from GroupNames
property,
and each series can use Legend.GroupIndex
property
to indicate its group.
Legend items are sorted as following:
- By group index, items without group (
GroupIndex=-1
) going first to avoid confusion with the last group. - By
Order
property, items without explicit order (Order=-1
) going last. - By creation order of series.
- For multiple items per series, by generation order (for standard series it is the order of points).
Sorted items are then added to the legend table in either by rows or by columns
depending on the ItemFillOrder
property.
Legend item text
The text of a legend item is generated by the corresponding series based on the Legend.Format
property.
This property is used as a first argument for the
SysUtils.Format
function,
with the second argument containing following data items:
- For per-series multiplicity:
- 0: Series
Title
- 1: Series
Index
- 0: Series
- For per-point multiplicity:
- Same as mark labels
If the property TextFormat is switched to tfHTML then HTML entities and tags can be embedded for special formatting of legend texts. See HTML for details.
User-defined legend items
Arbitrary legend items can be generated by overriding OnCreate
and OnDraw
events of series Legend
property.
Note that user-defined item count is controlled solely by
UserItemsCount
property and does not depend on Multiplicity
. Also note that GroupIndex
and Order
properties are actually per-item, so you can totally override entire legend from a single (perhaps fictive) series.
Arrows
Arrowheads can be drawn at the end of axis lines, constant lines, mark links, etc.
It is controlled by TChartAxis.Arrow
, TConstantLine.Arrow
, TChartMarks.Arrow
correspondingly.
Arrowhead shape is determined by Width
, Length
and BaseLength
properties,
for example:
- Thin wedge:
BaseLength = 0
- Triangle:
BaseLength = Length
- Rhombus:
BaseLength = 2 * Length
- Inverted Triangle:
BaseLength > 0
,Length = 0
This image shows these arrows created for Length=10
and Width=5
.
Transparency
Transparency
property of the series represents a level of transparency from 0 (fully opaque) to 255 (fully transparent -- i.e. invisible).
Compatibility note: FPVectorial and TFPCanvas drawers currently do not support transparency because of limitations of the underlying libraries. Printer and WMF drawers can not support transparency in principle.
Optimization note: Transparency support in the LCL is rudimentary, so current TCanvas drawer implementation may be slow with many transparent series and large charts. To improve efficiency, it is recommended to use as few different transparency levels as possible and to not interleave series with different transparencies. Alternatively, use BGRABitmap as back-end, since it has faster transparency implementation.
ChartStyles
TChartStyles
can be employed to control the appearance of the "layers" of area, line, and bar series with multiple y values. They can also be used to colorize the regions between axis ticks in a banded way.
Метки
Marks annotate certain points of the chart. These points can be defined by a series or an axis. Typically, mark consists of some graphical element (such as an axis tick) and a text label. However, either of these elements can be omitted.
You can see examples in the "labels" demo.
Mark labels
The label text can be enclosed in a box, controlled by LabelBrush
and Frame
properties.
The text itself is created based on the data source items, with the help of Format
property.
This property is used as a first argument for the
SysUtils.Format
function,
with the second argument containing following data items:
- 0: Y
- 1: Y as a percentage of the Y total
- 2: Text
- 3: Y total
- 4: X
Where "Y total" is the sum of all Y values for this source. Note that not all sources supply all the items above.
Some pre-defined formats can be set via the Style
property.
If the source is mutli-valued,
YIndex
property determines which Y value is used.
If YIndex = -1
, a separate label is displayed for each Y value, which is useful for stacked series.
The text is rendered using the LabelFont
. Note in particular that TAChart supports arbitrary
font Orientation
.
Mark labels are usually included in margins calculation to guarantee that all labels fit in the viewport.
This behavior can be turned off by setting AutoMargins
property to false
.
Multi-line marks
If the mark text contains LineEnding
character sequence, it is split into several lines.
Lines of different length are aligned according to Alignment
property.
HTML codes in marks
If the property TextFormat is switched to tfHTML then HTML entities and tags can be embedded for special formatting of marks. See HTML for details.
Mark positions and attachment
The mark position relative to the marked point is determined by the marks owner (series or axis).
Common mark properties include Distance
, which measures the distance
from the origin point to the attachment point in image units, and Attachment
, which controls
whether the attachment point is considered to be in the center or at the edge of the label box.
Additionally, basic chart series have a property MarkPositions
specifying
the direction of labels' offsets relative to series data points as following:
- lmpOutside -- away from the center of the data points cloud; for TBarSeries and TAreaSeries it has a special meaning: away from the ZeroLevel defined for this series.
- lmpPositive -- positive direction of series' Y axis
- lmpNegative -- negative direction of series' Y axis
- lmpInside -- towards the center of the data points cloud; for TBarSeries and TAreaSeries: towards the ZeroLevel
In Lazarus 2.0+, TBarSeries and TAreaSeries have an additional property MarkPositionCentered
which allows to center the marks origins between data points and zero level. In order to place marks exactly at the center of the bars of a BarSeries or at the center of the drop line of an AreaSeries, the following properties must be changed additionally: Marks.Distance = 0
, and Marks.Attachment = maCenter
.
Rotation of marks
Marks can be rotated by any angle in a resolution of 1/10 degree by modifying the Orientation of their font; it is specified by the 10-fold value in degrees, i.e. the value 450 refers to an angle of 45°. 0° means horizontal orientation, the angle increases in the counter-clockwise direction.
The rotation normally occurs with respect to the center of the label. Axis and series marks additionally have a property RotationCenter to shift the center of rotation to an edge of the text:
- raCenter -- default setting, i.e. rotation occurs around the text center
- raLeft -- the rotation center is at the left edge of the label.
- raRight -- the rotation center is at the right edge of the text.
- raEdge -- ignored in case of series marks (will be replaced by raLeft). But in case of axis marks the center of rotation is automatically moved to the text start or end in order to avoid rotation of the label into the chart.
Drawers
For low-level drawing routines, TAChart uses special set of classes implementing IChartDrawer
interface.
This allows such features as printing charts and exporting them to SVG format.
These classes are called drawing back-ends or drawers for short.
Отрисовщик TCanvas
TCanvasDrawer
— это отрисовщик по умолчанию, используемый для отображения диаграммы в TCanvas. Это включает в себя экран и различные форматы растровых изображений. Изображение, созданное этим ящиком, используется в качестве эталона при разработке и отладке других серверных частей.
TFPCanvas drawer
TFPCanvasDrawer
is similar to TCanvas drawer, but based on TFPCanvas
(which is a TCanvas
analog implemented in the FCL instead of the LCL).
See the "nogui" demo for an example.
Although TFPCanvas
and, correspondingly, TFPCanvasDrawer
have a restricted implementation
of some TAChart features, their important advantage is the possibility they offer of compiling an application with the nogui widgetset.
This is particularly useful for Web applications, which can then generate raster chart images without any further graphic dependency, or a need to install X/Gtk/Qt on the server.
SVG drawer
TSVGDrawer
produces text stream with the image of the chart in SVG format.
Similarly to TFPCanvas drawer, it is independent of LCL and can be used in Web applications
to generate vector charts in nogui widgetset.
See "save" demo for an example.
For this drawer, image unit is an SVG canvas unit instead of a pixel.
Note that due to the nature of SVG, there is no way to measure font dimensions, so they are approximated crudely.
This may result in problems like label text not fitting in the mark rectangle, especially in browsers
like Firefox that do not support textLength
attribute.
OpenGL drawer
TOpenGLDrawer
draws chart on the current OpenGL context.
It is suitable to be used in games and other OpenGL-only applications.
OpenGL drawer expects, but does not set by itself, an orthogonal projection. See "opengl" demo for an example.
Note that, like in OpenGL itself, TOpenGLDrawer
font support is extremely limited.
Отрисовщик принтера
TPrinterDrawer рисует диаграмму на холсте принтера. Он не очищает страницу.
Хотя холст принтера является потомком TCanvas
, и поэтому печать может выполняться с использованием отрисовщика по умолчанию, TPrinterDrawer
выполняет правильное масштабирование координат изображения в соответствии с DPI принтера и экрана.
Вы можете использовать этот отрисовщик для экспорта диаграммы в формат PDF с помощью одного из доступных продуктов для записи PDF.
См. пример демку 'print'.
Обратите внимание, что этот отрисовщик находится в отдельном пакете TAChartPrint.
AggPas drawer
TAggPasDrawer
draws chart using AggPas library.
AggPas offers high-speed antialiased drawing and is included in Lazarus sources. Unfortunately, the library is currently not maintained and there are some limitations in TAChart support.
Note that this drawer is located in a separate TAChartAggPas package.
BGRABitmap drawer
TBGRADrawer
draws chart using BGRABitmap library.
BGRABitmap is recently created and actively developed graphics library, offering, in particular, anti-aliasing and rich selection of gradients.
Currently BGRABitmap supports all TAChart features, but is somewhat slower then other drawing methods.
Note that this drawer is located in a separate TAChartBGRA package,
which depends on external bgrabitmappack
package.
FPVectorial drawer
TFPVectorialDrawer
draws chart using fpvectorial library.
FPVectorial offers exporting to various vector formats,
including SVG, PDF, CorelDraw and even instructions for metal cutting machines.
It currently has some limitations in TAChart support, but is actively developed.
Note that this drawer is located in a separate TAChartFPVectorial
package,
which depends on fpvectorialpkg
package.
WMF drawer
TWindowsMetafileDrawer
draws chart into a Windows Metafile.
It uses WinAPI directly, and so will only work on Windows. WMF support has been added to fpvectorial which provides a cross-platform alternative to this package.
Chart navigation consists of two parts: moving logical extent around without changing zoom factor, and visualizing the logical extent's position and size relative to the full extent.
Moving extent (but not visualizing it) is possible by using panning tools.
You can see examples in the "navigation" demo.
Scroll bars
TChartNavScrollBar
is a TCustomScrollBar
descendant with additional Chart
property
referencing the chart. TChartNavScrollBar
synchronizes its position with chart extent in both directions.
If the logical extent is equal to or larger than the full extent, navigation scroll bar does nothing.
Setting AutoPageSize = true
lets TChartNavScrollBar
to pick page size proportional to the logical extent.
Note that Min
and Max
properties are not changed automatically.
It is recommended to set Min = 0
and Max
to some fairly large integer value to avoid rounding issues.
Also note that TChartNavScrollBar
does not automatically align or attach itself to a chart,
so it can be arbitrarily positioned on the form.
TChartNavPanel
component displays logical and full extent of an assigned chart as differently colored rectangles,
allowing user to drag the logical extent rectangle if AllowDragNavigation = true
.
If MiniMap = true
, the panel additionally displays the chart series.
TChartNavPanel
can have arbitrary size, but it is recommended to keep height to width proportion the same as in the assigned chart. Setting Proportional = true
will enforce the same proportions even if the above condition is not met, at the cost of some wasted space on the panel.
Additional components
Legend panel
TChartLegendPanel
provides a legend which can be placed anywhere on the form. The legend is taken from the chart with is assigned to the property Chart
of the LegendPanel. The chart’s own legend should be turned off.
Chart listbox
TChartListbox
is a versatile legend replacement which displays an icon and the series title for each series of the chart attached to the property Chart
of the listbox. But in addition to the standard legend, it also has checkboxes for each series. Unchecking a checkbox hides the associated series, checking it shows the series again. The listbox listens to changes in the associated chart and updates automatically.
The property CheckStyle
can be used to switch the listbox from a checkbox-like behavior (cbsCheckbox
, an arbitrary combination of series can be checked) to a radiobutton-like behavior (cbsRadioButton
, only a single series can be checked). Depending on CheckStyle
either a radiobutton or a checkbox state icon is displayed for each series.
Events are fired when the checkbox/radiobutton or the series title are clicked (OnCheckboxClick
or OnItemClick
, respectively), or when the series icon is double-clicked (OnSeriesIconDblClick
). The latter event is thought to open a dialog for changing the series color, pointer style, series title etc.
The listbox items are collected in a different way than for a conventional legend. The populating process ignores the series property Legend.Visible
which controls whether the series is to be shown in the legend or not. Instead of it, there is an event OnAddSeries
in which the var
parameter Skip
should be set to true
if the series passed as another argument should be excluded from the listbox. Every series is listed only with a single item, i.e. the series’ Multiplicity
is ignored as well. Moveover, grouping of items is not supported either.
Chart image list
TChartImageList collects the icons displayed for each series in the legend and can be used for imagelist-aware controls, such as treeviews, listviews or menus to show icons for each series. The icons are extracted from the chart which is assigned to the Chart property of the component. The image list is notified of changes in the chart and updates its images automatically whenever something changes with a series. The event OnPopulate is fired if the image list is rebuilt.
Note that this kind of image list is volatile, i.e. its images are not stored in the form's lfm file. Nevertheless, at runtime, it can be used as a standard image list with other images. Just add these non-series images before assigning the chart to the image list. Use the property FirstSeriesIndex to get the image index of the first series contained in the image list. Alternatively, find the image index of a specific series by calling the function ImageIndexOfSeries(series).
In Laz 2.1+ the TChartImageList can be used also at designtime. It stores only those images not assigned to a series.
Chart combobox
The TChartCombobox is an extended combobox. Depending on the property Mode
(ccmPointerStyle
, ccmPenStyle, ccmPenWidth
, ccmBrushStyle
) it is populated with names and corresponding icons for pointer style, pen style, pen width or brush style selection. Therefore, it is useful for gui elements in which the user can modify the appearance of series and other chart objects.
The combobox is not linked to a particular chart. Use the OnChange
event to transfer the modified property to the series.
TeeChart compatibility
TeeChart is a standard set of charting components used by Delphi. Although TAChart does not have a goal to to be compatible with TeeChart, basic feature set and names are very similar, so simple examples may work in both libraries equivalently.
More complex features -- in particular, multi-value series, series sources, multiple axes -- are implemented differently from TeeChart. This is by design and will not change. See comparison page for more detailed info.
To assist porting of TeeChart code to the TAChart, you can use
TAChartTeeChart
unit. It contains class helpers adding
or emulating some TeeChart-specific properties and methods.
Note that it is NOT recommended to use this unit for normal development, since the emulation is only intended to simulate the subset of features implemented in TeeChart, and may not be reliable when used in conjunction with the full set of TAChart features.
Technical details
Drawing order
Chart drawing consists of three stages:
- Preparation: At this stage, various internal data structures are initialized.
- Measurement: At this stage, the chart calculates the sizes of all elements, and optimizes them for best presentation. Optimization may require several iterations, so the measurement stage is often the heaviest one both in terms of implementation complexity and running time.
- Drawing: At this stage, the actual chart image is displayed.
There also exists an ordering among various chart elements:
- Background (using
TChart.Color
property). - Back-wall (using
TChart.BackColor
property). - Series and axes according to
ZPosition
property. For each series and axis, graphic elements are drawn before marks. Note that this protects marks against hiding by the axis/series they belong to, but not by other axes/series. - Legend.
- Tools.
Note that ZPosition
works for both 2-D and 3-D charts, so you can overlay series and axes in arbitrary order.
Coding style
Historically FPC, Lazarus and LCL sources contain a mix of coding styles, with the general rule being "be consistent with the surrounding code".
However, since TAChart has many fewer contributors, it is feasible to adopt and maintain a consistent style across all TAChart code. If you want to contribute to TAChart, please format your code accordingly. Also remember that any coding style may be violated in certain situations when the reason is good enough, but please explain that reason if you do so.
Spaces
- No double spaces anywhere.
- Spaces after: operations, comma, semicolon, assignment, closing parenthesis in expressions (not in function calls).
- Spaces before: operations, assignment, opening parenthesis in expressions (not in function calls).
Lines
- No double empty lines anywhere.
- Empty lines between procedures, classes, unit sections. Rare empty lines inside procedure bodies to separate logical blocks.
- Line length below 80 characters, with rare exceptions.
- Single statement per line, except if ... then {exit|break|continue} and some rare cases of mass assignment.
- If the line is too long, line breaks may be inserted after at the following symbols, in order of decreasing priority: keywords, opening parenthesis, opening square bracket, semicolon, comma, operation.
Indentation and blocks
- Always two spaces, both for blocks and continuation lines.
- begin on the same line as the control statement, end aligned with the control statement.
- end always alone on the line. In particular, write end else begin on two lines.
- Put then or do on a separate line to separate a complex condition from the statement body:
while long condition or another long condition do loop body
- Use begin/end only when necessary (i. e. not for single statements).
Comments
- Put a license header at the beginning of every file.
- Single-line comments everywhere except the license header and auto-generated class headers in implementation section.
- Use only full sentences in comments, starting with a capital letter and ending with a full stop.
- Comments should be placed before commented code, except in rare cases where a comment fits at the end of the same line.
- Comments should only include information not evident from the source. In particular, choose meaningful procedure and argument names in preference to adding comments describing their usage.
Names
- Constants use ALL_CAPS_WITH_UNDERSCORE, everything else use CamelCase.
- Local variables start with a lower-case letter, everything else starts with an upper-case letter, even when FPC library disagrees (e.g. ``Math``, not ``math``).
- Class fields start with 'F', arguments start with 'A', types start with 'T', TAChart units start with 'TA'.
Variable declarations
- Initialize when possible.
- Local variables after nested procedures unless used by them.
- Group variables by type.
Classes and methods
- Methods are grouped per-class, methods inside class are sorted alphabetically both in interface and implementation. There should be zero Code Observer warnings about 'Unsorted members'.
- If there is a need to group methods by topic, use visibility specifiers as topic separators. In particular, group overridden methods separately from the newly introduced ones.
- Use strict private/strict protected visibility where possible.
Hints and warnings
- Code should compile with zero hints and warnings.
- Silence any "unused parameter" warning with the ``Unused`` procedure from the TAChartUtils unit, or use the {%H-} Lazarus IDE directive.
Control flow
- Use exit or raise to abort method execution in case of a violated pre-condition.
- Use enumerators where possible.
- Use with carefully, and only where its use significantly saves code size and in the minimal possible range.
- Limit all procedures to 50-60 lines, and use nested procedures liberally.