
Оформление поля графиков и диаграмм, печать и запоминание
Теперь рассмотрим некоторые страницы Редактора Диаграмм компонента Chart и соответствующие свойства и методы, связанные с оформлением поля графиков и диаграмм. Начнем с закладки General страницы Chart, показанной на рис. 3. Группа элементов Zoom характеризует описанную возможность пользователя выделять и увеличивать фрагмент графика или диаграммы. Индикатор Allow Zoom включает и выключает эту возможность. То же самое можно делать, устанавливая во время проектирования или программно во время выполнения свойство AllowZoom. Если увеличение разрешено, то индикатор Animated Zoom (свойство AnimatedZoom) позволяет включить или выключить анимацию этого процесса. Если индикатор не включен (AnimatedZoom = false), то увеличение масштаба происходит мгновенно. При включенном индикаторе изменение масштаба происходит плавно. Степень плавности определяется индикатором Steps (свойство AnimatedZoomSteps), указывающим число шагов анимации.
Рис. 3 Закладка General Редактора Диаграмм
Группа радиокнопок AllowScroll (свойство AllowPanning) определяет возможность пользователя прокручивать наблюдаемую часть графика во время выполнения, нажимая правую кнопку мыши. Возможные значения свойства: pmNone (кнопка None) — прокрутка запрещена, pmHorizontal (кнопка Horizontal), pmVertical (кнопка Vertical) и pmBoth (кнопка Both) — разрешена соответственно прокрутка только в горизонтальном направлении, только в вертикальном или в обоих направлениях Окна Margin определяют свойства MarginLeft, MarginTop, MarginRight, Mar-ginBottom — левое, верхнее, правое и нижнее поля графика.
Включение индикатора ClipPoints (свойство ClipPoints) определяет, что точки графика будут рисоваться только внутри координатной сетки. Если этот индикатор выключить (ClipPoints = false), то, например, при увеличении масштаба какого-то фрагмента график выйдет за пределы координатной сетки, что вряд ли целесообразно когда-либо делать.
Кнопка Print Preview реализует процедуру ChartPreview — предварительный просмотр графика перед печатью. Процедура объявлена в файле teeprevi.pas следующим образом:
procedure ChartPreview(AForm: TForm; AChart: TChart);
В качестве параметров в нее передается форма, содержащая график, и компонент Chart. Процедура, как и соответствующая кнопка в окне рис. 7.3, вызывает диалоговое окно. В окне предварительного просмотра пользователь может выбрать принтер, установить его характеристики, выбрать опции печати и произвести саму печать. Использовать все эти возможности во время проектирования вряд ли оправданно. А во время выполнения вызвать окно предварительного просмотра можно кодом:
uses teeprevi;
ChartPreview(Forml, Chartl);
Поскольку речь пошла о печати, рассмотрим еще несколько соответствующих методов Chart. Методы PrintLandscape и PrintPortrait вызывают печать соответственно в альбомной (горизонтальной) или книжной ориентации. Сначала эти методы осуществляют соответствующую ориентацию, затем вызывают метод Print, а после печати восстанавливают предыдущую ориентацию. Метод Print можно вызывать и явно. Он осуществляет печать с текущей ориентацией. Ориентация может быть предварительно установлена методом PrintOrientation, в который в качестве параметра передается ориентация: poLandscape или poPortrait. Впрочем, то же самое можно сделать, просто обращаясь к свойству Orientation объекта Printer. Например:
Printer.Orientation :- poPortrait;
Для того чтобы использовать объект Printer или метод PrintOrientation, надо подключить к проекту оператором uses модуль printers
Печать в рамку заданного размера и в заданном месте страницы позволяют методы PrintPartial и PrintRect. В оба них передается в качестве единственного параметра область печати на канве принтера типа TRect. Максимальная разрешенная область определяется координатами (0, 0, Printer.Page Width - 1, Printer.Page-Height - 1). Основное различие методов PrintPartial и PrintRect заключается в том, что PrintRect вызывает методы BeginDoc и EndDoc объекта Printer. Это значит, что на странице можно напечатать только один график или диаграмму. A PrintPartial этих методов не вызывает и, следовательно, можно напечатать на странице несколько графиков и добавить к ним, например, какой-то текст.. Но зато вам надо программно вызывать методы BeginDoc и EndDoc. Если все эти операции с объектом Printer вам непонятны, придется посмотреть об этом объекте во встроенной справке Delphi или прочитать в литературе.
Еще один метод, предоставляющий возможность печатать графики с какими-то дополнениями — это метод PrintPartialCanvas, объявленный как:
procedure PrintPartialCanvas(PrintCanvas: TCanvas;
Const PrinterRect: TRect);
Например, его можно вызвать следующим образом:
Chartl.PrintPartialCanvas(Printer.Canvas, Rect(100, 100, 800, 800));
Теперь вернемся к окну на рис. 3 и рассмотрим кнопку Export. Эта кнопка вызывает диалоговое окно, в котором можно занести изображение графика в буфер обмена или в файл. Вряд ли имеет смысл использовать эти возможности во время проектирования. А вот программно во время выполнения такие операции очень нужны. Поэтому рассмотрим соответствующие им методы.
Компонент Chart может работать с четырьмя возможными форматами. Первый из них — специализированный формат компонентов серии TeeChart. Этот формат сохраняет не только само изображение, но и все настройки серий компонента Chart. Второй формат — битовые матрицы .bтр. Этот формат универсален, но размер файлов в этом формате велик. Формат .wmf — это формат метафайлов (Metafiles). Он обеспечивает существенно меньшие размеры файлов, поскольку сохраняет не отдельные пикселы, а способы, использованные при построении изображения. Есть в метафайлах и еще преимущества — они обеспечивают простое и качественное изменение размера графиков. Но это несколько устаревший формат. Более новый формат метафайлов — .emf, используемый в 32-разрядных версиях Windows. Это формат векторной графики (Enhanced Metafiles) обладает теми же достоинствами метафайла, но более приспособлен для современных программ.
Сохранение изображений в описанных форматах осуществляется соответственно методами:
procedure SaveChartToFile(AChart:TCustomChart; Const AName:String);
procedure SaveToBitmapFile (Const FileName: String );
procedure SaveToMetafile(Const FileName: String);
procedure SaveToMetafileEnh(Const FileName: String);
Во все эти методы передается FileName — имя файла с соответствующим расширением. Вообще говоря, расширения файлам можно давать любые. Но лучше не отступать от общепринятого, поскольку многие приложения Windows распознают файлы именно по их расширениям.
Если вы сохранили файл процедурой SaveChartToFile, то в дальнейшем можете загрузить его в компонент Chart процедурой LoadChartFromFile:
procedure LoadChartFromFile(Var AChart:TCustomChart; Const AName:String);
Только имейте в виду, что процедуры SaveChartToFile и LoadChartFromFile объявлены в модуле teestore, который должен быть подключен к проекту.
Помимо возможности сохранения изображений в файлах, в компоненте Chart предусмотрена возможность копирования его в буфере обмена Clipboard. Изображение может копироваться в одном из трех описанных выше форматов: .bтр, .wmf, .emf. Это делается методами:
Procedure CopyToClipboardBitmap;
Procedure CopyToClipboardMetafile(Enhanced:Boolean) ;
Первый из них копирует изображение как битовую матрицу. А формат, в котором копирует изображение метод CopyToClipboardMetafile, зависит от значения аргумента Enhanced. Если Enhanced = true, то используется формат EMF. При значении Enhanced = false используется формат WMF. Во время проектирования, если вы захотите использовать копирование изображения в буфер обмена, нажмите кнопку Export в окне рис. 3, а в открывшемся диалоговом окне — кнопку Сору to Clipboard.
Теперь остановимся коротко на других элементах оформления окна графиков и диаграмм. Закладка Title, страницы Chart окна Редактора Диаграмм (рис. 5) позволяет задать свойства заголовка и подписи графика (тексты «Синус и косинус» и «Пример простого графика» на рис.1). Выпадающий список в левом верхнем углу окна позволяет выбрать, что в данный момент вы хотите задавать: заголовок (Title) или подпись (Foot). В компоненте Chart есть соответствующие свойства Title и Foot — объекты типа TChartTitle, обладающие рядом подсвойств). Основное из них — Text типа TStrings. Это может быть многострочное пояснение графика. В окне рис. 1 текст задается в нижней панели. Атрибуты текста задаются в окне рис. 5 при нажатии кнопки Font. Свойство Frame объектов типа TChartTitle описывает рамку вокруг текста. В окне рис. 5 основные свойства этой рамки задаются при нажатии кнопки Border. В диалоговом окне, открывающемся при нажатии этой кнопки, можно задать тип линии (Style), ее толщину (Width), цвет (Color) и видимость (Visible). На рис. 1 Visible = false, так что рамка не видна.
Рис. 5 Закладка Title Редактора Диаграмм
Если задать для рамки Visible = false (не путайте с аналогичным индикатором Visible в окне рис. 5, который определяет видимость текста), то индикатор Adjust Frame на рис. 5 позволяет управлять выравниванием рамки (свойством Adjust-Frame). Если этот индикатор выключен, то рамка вытягивается на всю ширину графика. При включенном индикаторе рамка окружает только текст.
Кнопка Back Color позволяет задать фон надписи, кнопка Pattern — штриховку фона. Группа радиокнопок Alignment определяет выравнивание текста по левому краю, центру или правому краю.
Закладка Panel страницы Chart окна Редактора Диаграмм (рис. 6) позволяв настраивать общий вид поля графика. Группы радиокнопок Bevel Inner и Bevel Oute определяют вид внешней кромки поля (выпуклый, утопленный, плоский). Кнопк Panel Color позволяет задать цвет фона поля. Индикатор Border определяет наличи рамки вокруг поля графика. Группа управляющих элементов Gradient позволяв подсветить поле переливающимся цветом, изменяющимся в различных направле ниях. Это довольно красиво, но, конечно, целесообразно применять для каких-то де монстрационных и рекламных графиков и диаграмм, а не как рабочий инструмент.
Рис. 6 Закладка Panel Редактора Диаграмм
Группа управляющих элементов Back Image позволяет заполнить поле каким-то рисунком или орнаментом. Нажатие кнопки Browse вызывает диалог открытия файла, позволяющий выбрать соответствующее изображение. Если изо бражение выбрано, становятся доступными элементы Inside и Style. Включение ин дикатора Inside концентрирует изображение только внутри координатных осей, При выключенном индикаторе изображение занимает всю площадь. Радиокнопки Style указывают способ отображения изображения: Stretch — рисунок увеличивается до размеров всей покрываемой площади, Tile — рисунок, если его размер не велик, многократно дублируется, чтобы покрыть всю площадь, Center — рисунок однократно отображается в центре. Все это также можно сделать довольно красиво, но только для демонстрационных и рекламных целей.
Закладка Legend страницы Chart (рис. 7) управляет настройкой легенды — списка обозначений. Основной индикатор на этой странице — Visible, определяющий отображение легенды. Выпадающий список Legend Style (свойство Legend-Style) определяет, что именно должно отображаться в легенде. Выбор Series Names (значение IsSeries) задает отображение названий серий (как на рис. 1). Выбор Series Values (значение lsValues) задает отображение значений отдельных точек. Это, конечно, неприменимо к графикам, но может быть полезно для ряда типов диаграмм. Выбор Last Values (значение IsLastValues) задает отображение последнего значения каждой серии. Это может быть полезно, если график или диаграмма строятся в реальном масштабе времени, например, очередные точки поступают от какого-то внешнего устройства. Тогда в легенде будут отображены последние поступившие сведения. Выбор Automatic (значение IsAuto) эквивалентен выбору Series Names, если отображается несколько серий, и выбору Series Values, если имеется только одна активная серия. Выпадающий список Text Style (свойство Text-Style) определяет размещение элементов надписей в легенде: Plain — только названия серии или точки, Left Value — слева значение, а справа название и т.д. Остальные элементы в окне рис. 7 определяют положение и оформление легенды. Поэкспериментируйте с этими элементами, и вы легко поймете их назначение.
Рис. 7 Закладка Legend Редактора Диаграмм
Закладка Legend определяет свойства легенды, общие для всех серий. А отображение в легенде той или иной из активных серий можно указать в свойствах конкретной серии, устанавливаемых в закладке General страницы Series (см. индикатор Show In Legend на рис. 8)
Основные методы базового класса серий TChartSeries и их применение
В компоненте Chart объявлено много классов, соответствующих различным типам графиков и диаграмм. Все они наследуют базовому классу TChartSeries. Основные свойства этого класса были рассмотрены раньше.
Остановимся на некоторых методах класса TChartSeries. Начнем с методов добавления в серию новой точки.
AddXY – Выполняет добавление новой точки в серию, если тип серии предполагает численные значения аргумента X и функции Y
function AddXY(Const AXValue, AYValue: Double; Const AXLabel: String; AColor: TColor): Longint;
Параметры AXValue и AYValue задают значения X и Y. He обязательный параметр AXLabel задает текст метки, соответствующей добавляемой точке. Этот текст может выводиться около соответствующих делений координатной оси или как текст значения функции Y. Не обязательный параметр AColor задает цвет точки. Если он не задан, для точки применяется цвет SeriesColor, заданный для данной серии. Функция возвращает индекс новой точки в массиве Values.
Приведем примеры:
Series 1.AddXY(0,5, 'начало'#13'бизнеса',clRed); Seriesl.AddXY(1,6,'',clRed);
Seriesl.AddXY(3,8);
Первый из приведенных операторов задает и метку (причем, двухстрочную) и цвет — красный. Второй оператор задает цвет, но не задает метку. Третий оператор не задает ни метку, ни цвет. Значит, будет или принят цвет SeriesColor, установленный для данной серии, или цвет каждой точки будет различаться, если установлено свойство ColorEachPoint (см. свойства серий).
Для задания цвета можно использовать функцию GetDefaultColor(ind), которая возвращает цвет с индексом ind из палитры по умолчанию. Задание каждой новой точке нового цвета может быть осуществлено этой функцией с изменяющимся индексом ind. Отличие от установки в true свойства ColorEachPoint будет заключаться в том, что вы можете управлять процессом установки цвета и для каких-то точек задавать определенные цвета.
Если ось является осью дат/времени, то задание соответствующих значений может осуществляться функцией EncodeDate, в которую в качестве параметров передаются год, месяц и день. Например:
for i:=l to 31 do
Seriesl.AddXY(EncodeDate(2007,5,i) , 10*i) ;
AddY – Используется для занесения точки в серию типа, который не имеет значений X:
function AddY(Const AYValue: Double; Const AXLabel: String; AColor: TColor): Longint;
Параметр AYValue указывает значение Y, параметр AXLabel — метку точки, параметр AColor — цвет. Как и в предыдущей функции, параметры AXLabel и AColor не обязательные. Функция возвращает индекс новой точки в массиве Values.
AddNull – используется чтобы прервать график в каких-то точках, а затем опять продолжить его. Например, в каком-то диапазоне дат нет данных и значение функции неизвестно.
function AddNull(Const ALabel: String): Longint;
Этот метод вставляет пустую точку и прерывает график. Точки, окружающие пустую, не соединяются друг с другом. Метод работает правильно только для графиков типа TLineSeries. Для графиков типов TFastLineSeries и TAreaSe-
ries метод дает неправильные результаты.
AssignValues – копирует в данную серию все точки другой серии Source.
procedure AssignValues (Source: TChartSeries);
Если вам не требуется копирование, а просто надо, чтобы две серии работали с одними и теми же данными, это делается проще и экономнее заданием в свойстве DataSource одной серии ссылки на другую серию, в которой список точек уже заполнен.
Изменить значение некоторой точки с известным индексом можно, по значениям списков XValues (значения X) и YValues (значения Y). Например, операторы
Seriesl.YValues.Value[1] := 25; Chartl.Repaint;
заменяют значение Y второй точки (индексы отсчитываются от 0) на 25 и обновляют отображение данных.
Индекс необходимой точки не всегда известен, особенно, если в списке используется автоматическое упорядочивание точек (свойство Order не равно loNone). Тогда можно найти этот индекс с помощью метода Locate:
function Locate (Const Value:Double):Longint;
который возвращает индекс точки, имеющей значение X, равное указанной величине Value. Если точки с указанным значением нет, возвращается значение -1. Например, следующий код изменяет значение Y точки с аргументом, соответствующим дате 06.04.07:
i := Seriesl.XValues.Locate(EncodeDate(2007,4,6));
if i >= 0 then
begin
Seriesl.YValues.Value[i] := 25;
DBChartl.Repaint;
end;
Delete – Удаление точки
procedure Delete(Valuelndex: Longint);
удаляет точку с индексом Valuelndex.
Clear – полностью очищает список точек серии.
SwapValuelndex: меняет местами точки с индексами а и b.
procedure SwapValuelndex(a, b: Longint);
Count возвращает текущее число точек, имеющихся в списке серии.
VisibleCount возвращает число точек, видимых в данный момент. Оно может отличаться от Count, если пользователь или программа изменяла масштаб изображения.
CalcXPos и CalcYPos возвращают соответственно горизонтальную и вертикальную координату (в пикселах) точки с индексом Valuelndex. Используется, если надо дополнить график или диаграмму какими-то своими изображениями или надписями
Экранные координаты соответствуют координатам компонента Chart. Координаты его левого верхнего угла равны (0, 0). Индексы точек начинаются с 0.
CalcXSizeValue и CalcYSizeValue возвращают число пикселов, соответствующих отрезку оси горизонтальной и вертикальной осей длиной Value. Эти методы позволяют переводить интервалы значений координат осей в интервалы экранных координат.
XScreenToValue и YScreenToValue: Они возвращают значения координат точек, соответствующие экранным координатам ScreenPos
function XScreenToValue(ScreenPos: Longint): Double;
function YScreenToValue(ScreenPos: Longint): Double;
GetCursorValues: возвращает в качестве значений своих параметров х и у значения координат точки, соответствующие текущему положению курсора
procedure GetCursorValues(Var x, у: Double);
Например, следующий обработчик события OnClick компонента Chart обеспечивает отображение в метке Labell координат точки щелчка:
procedure TForml.ChartlClick(Sender: TObject);
var xt, yt: double;
begin
Seriesl.GetCursorValues(xt, yt);
Labell.Caption := 'X = '+ Seriesl.XValueToText(xt) + ' Y = '+
Seriesl.YValueToText(yt) ;
end;
Помимо метода GetCursorValues в этом примере использованы методы XValueToText и YValueToText, переводящие значения координат в текст. Конечно, можно было бы для этих целей воспользоваться методом FloatToStr. Преимущество методов XValueToText и YValueToTex в том, что они используют шаблоны отображения, заданные для координат серии. К тому же, эти методы сработают и для числовых координат, и для координат типа дата/время.
Если вы создадите аналогичный обработчик события OnMouseMove компонента Chart, то он будет отображать в метке координаты курсора постоянно, пока курсор перемещается над этим компонентом:
procedure TForml.ChartlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var xt, yt: double;
begin
Seriesl.GetCursorValues(xt, yt) ;
Labell.Caption := 'X = '+ Seriesl.XValueToText(xt) + ' Y = '+
Seriesl.YValueToText(yt);
end;