Организация хранения графиков в диаграмме Построение диаграмм В составе визуальной библиотеки компонентов среды Delphi практически нет компонентов, рожденных вне стен Borland. Корпоративные возможности и профессиональный уровень программистов этой компании вполне позволяют обходиться своими силами. Наглядное тому подтверждение – две сотни всевозможных элементов управления на палитре компонентов Delphi 8. Исключений из этого правила немного. Одно из них – компоненты диаграммы. На такой беспрецедентный шаг Borland вдохновили (не побоюсь этого слова) блестящие возможности элементов управления TChart (страница Additional) и TDBChart (страница Data Controls) по построению сложнейших диаграмм. Автор этих компонентов – программист компании Steema Software Дэвид Бернеда (David Berneda). При работе с диаграммами к проекту автоматически подключается модуль Chart (для компонента TChart) или DBChart (для компонента TDBChart). К сожалению, исходный код модулей для нас недоступен, но это законное право его владельца. Рис. 18.1. Иерархия наследования Из немногочисленной информации о диаграммах доподлинно известно, что оба класса построены на основе обычной панели TPanel(рис. 18.1). Специализирующийся на обслуживании баз данных компонент TDBChart требует, чтобы на компьютере была установлена система доступа к данным BDE (BorlandDatabase Engine). Компонент TChart С точки зрения ООП диаграмма представляет собой весьма сложную конструкцию. В своем составе TChart (TDBChart) инкапсулирует впечатляющий перечень взаимодействующих между собой и даже, можно сказать, поддерживающих друг друга в трудную минуту объектов. Управление большинством из них организовано как из Инспектора объектов, так и из специализированного редактора, вызываемого из контекстного меню компонента.  Рис. 18.2. Ключевые элементы диаграммы К ключевым интегрированным объектам (рис. 18.2) относятся экземпляры классов: • TChartSeriesList – контейнер для хранения отдельных графиков (в самом общем случае отдельный график реализуется на базе класса TChartSeries); • TChartAxis, TChartDepthAxis– координатные оси диаграммы; • TChartLegend – легенда (подписи графиков) диаграммы; • TChartTitle – заголовок диаграммы. Над оформлением диаграммы кропотливо трудится ряд специализированных графических классов: • TCanvas3D – трехмерный холст (канва) диаграммы; • TChartGradient – класс, описывающий способ заливки диаграммы; • TChartPen – класс, определяющий характеристики пера; • TChartBrush – вид кисти; • TChartWall – класс, описывающий способ прорисовки стен; • TView3DOptions – опции объемной графики. Большинство из перечисленных графических классов представляют собой логическое развитие хорошо нам знакомых TCanvas, TPen и TBrush. Организация хранения графиков в диаграмме Смысл существования компонента TChart состоит в умении хранить и выводить на экран разнообразные графики (потомки класса TChartSeries). Для «складирования» графиков в TChart предусмотрен специализированный контейнер. Если же контейнер пуст, то диаграмма представляет собой унылое зрелище и безответственно занимает драгоценное пространство на рабочей форме. Без связи с диаграммой график не более чем бесполезный инструмент. Хотя он и является вполне самостоятельным объектом, но из-за того что TChartSeries не умеет отображать свои данные, в отрыве от диаграммы практического интереса график не представляет. Обреченные жить в симбиозе, графики и диаграмма взаимодействуют благодаря свойству: propertySeries[Index : Longint] : TChartSeries; Это и есть врата на склад графиков компонента TChart. Для работы с отдельным экземпляром графика требуется указать его индекс. Обязанности главного счетовода возложены на метод: functionSeriesCount : Longint ; //только для чтения Только он знает количество графиков в контейнере. Обращаясь к свойствуSeries и владея информацией о количестве графиков, диаграмма способна управлять каждым из графиков, например окрасить их в небесные тона: fori:= 0 toChart1.SeriesCount -1 do withChart1.Series[ i ] doSeriesColor := clAqua; Во время разработки приложения для вставки, изменения или удаления графика из диаграммы используется специальный редактор (рис. 18.3). Для его вызова в режиме проектирования достаточно дважды щелкнуть по компоненту TChart.  Рис. 18.3. Внешний вид редактора компонента Содержимое контейнера допускается пополнять или освобождать во время выполнения программы. Для этого предусмотрен ряд методов. С операцией добавления нового графика в коллекцию лучше всех справится метод: procedureAddSeries(ASeries : TChartSeries); В качестве параметра в процедуру передается экземпляр графика, например созданный конструктором Create(). varASeries : TChartSeries; Begin ASeries:=TChartSeries.Create(Chart1); Chart1.AddSeries(ASeries); //… end; По сути метод AddSeries() просто сообщает графику, что теперь им единолично владеет диаграмма, вызвавшая этот метод. Обратная задача по экспроприации у контейнера отдельного графика обеспечивается процедурой: procedureRemoveSeries(ASeries : TChartSeries); Подчеркну, что здесь речь не идет об уничтожении экземпляра графика. Изъятый экземпляр просто покидает родительскую диаграмму (его свойство ParentChart переходит в nil). Позднее этот график без проблем можно вернуть на место или подключить к другой диаграмме. Для полной очистки контейнера вызывается процедура: procedureRemoveAllSeries; |