Построение графиков c visual studio

Обновлено: 07.07.2024

Компонента Chart (диаграмма) в Visual Studio довольно удобна, хотя для начинающих обычно сложно выбрать из множества её возможностей самые актуальные. К тому же, задокументировано-то всё лишь на MSDN.

Приведу несколько примеров, анализ которых поможет Вам быстро освоить основные приёмы работы с графиками и диаграммами в Visual C++. Все коды проверены в сборке Express 2010.

Пример 1. Добавим на форму компоненту Chart и выведем туда данные
Пример 2. Сделаем красивый Chart программно, можно по нажатию новой кнопки на той же форме
Пример 3. Вытащим данные из Chart в TextBox

Добавим какой-нибудь не очень сложный парсер, например, класс parser.cpp от Chaos Master.

Код выбранного нами парсера старый, так что нам придётся кое-что переделывать, например, строки char * в String ^ и обратно.

Добавим на форму компоненты textBox1 и label1 , напишем демо-код для применения парсера (вызывается по нажатию кнопки):

Возможно, понадобится изменить какие-то ещё мелочи, например, я в файле parser.cpp раскомментарил строку

Также ясно, что в начале файла form1.h добавлена строка

Теперь в поле ввода можно писать любые допустимые парсером выражения с переменной x , например, cos(x)+1 , текущее значение переменной x из программы подставится в выражение и его результат динамически подсчитается.

На основе показанных кодов легко сделать, например, программу построения графиков с интерпретацией введённой пользователем функции. Скажем, если выражение для функции с аргументом, обозначенным x , вводится в текстовое поле textBox1 , код построения графика функции в пределах от 0 до 3.14 с шагом, равным 0.1 , будет таким:

04.02.2014, 17:03; рейтинг: 34126

Элемент управления Chart — это объект диаграммы, предоставляющий события. The Chart control is a chart object that exposes events. При добавлении диаграммы на лист Visual Studio создает объект Chart, который можно запрограммировать напрямую, не обращаясь к объектной модели Microsoft Office Excel. When you add a chart to a worksheet, Visual Studio creates a Chart object that you can program against directly without having to traverse the Microsoft Office Excel object model.

Область применения: Сведения этого раздела применяются к документа-уровень проектов и добавить VSTO-в проектах для Excel. Applies to: The information in this topic applies to document-level projects and VSTO Add-in projects for Excel. Дополнительные сведения см. в разделе функций по типам приложений и проектов Office. For more information, see Features available by Office application and project type.

Создание элемента управления Create the control

Элементы управления Chart можно добавлять на лист Microsoft Office Excel во время разработки и во время выполнения в проекте на уровне документа. You can add Chart controls to a Microsoft Office Excel worksheet at design time or at run time in a document-level project.

Вы можете добавить элементы управления Chart на лист во время выполнения надстройки VSTO. You can add Chart controls to a worksheet at run time in a VSTO Add-in. Дополнительные сведения см. в разделе Практическое руководство. Добавление элементов управления диаграммы на листы. For more information, see How to: Add Chart controls to worksheets.

При закрытии листа динамически созданные объекты диаграммы не сохраняются на листе как элементы управления ведущего приложения. Dynamically created chart objects are not persisted in the worksheet as host controls when the worksheet is closed. Дополнительные сведения см. в разделе Добавление элементов управления в документы Office во время выполнения. For more information, see Add controls to Office documents at run time.

Форматирование Formatting

Любое форматирование, которое можно применить к Chart, также можно применить к элементу управления Chart. All formatting that can be applied to a Chart can also be applied to a Chart control. Это такие элементы форматирования, как границы, шрифты, тип диаграммы, линии сетки, условные обозначения и метки данных. This includes borders, fonts, chart type, gridlines, legend, and data labels.

События Events

Для элемента управления Chart доступны следующие события: The following events are available for the Chart control:

Posted on Ноябрь 27, 2010

При работе с новой версией WPF 4.0 сталкиваешься с проблемой, а именно: если раньше компонент отрисовки графиков и диаграмм Chart при работе в Blend Studio был доступен на вкладке Controls, то теперь его там по умолчанию нет .Поэтому приходится подключать этот компонент вручную.

Шаг первый. Открываем/создаем проект WPF c помощью Visual Studio 2010

chart c visual studio

После открытия проекта в VisualStudio 2010 обратите внимание на панель инструментов (которая доступна при открытой главной форме приложения). В ней расположены основные элементы пользовательского интерфейса WPF (Button, CheckBox, ComboBox и др.). Как видим – компонента Chart здесь нет (см. рис. 1).

Шаг второй. Подключаем компонент для отрисовки диаграмм/графиков Chart к панели инструментов ToolBox

chart c visual studio

Для этого в панели инструментов ToolBox щелкаем правой кнопкой мыши и вызываем контекстное меню. В контекстном меню выбираем пункт «ChooseItems…» (см. рис. 2). После этого появляется диалоговое окно выбора элементов панели инструментов, как показано ниже на рисунке 3.

chart c visual studio

Выбираем вкладку WPF Components, в списке компонентов находим элемент Chart и помечаем его галочкой. Нажимаем клавишу OK .

chart c visual studio

Компонент Chart появился в списке ToolBox (рис. 4).
Примечание: не рекомендуется убирать галочки с других элементов, т.к. в этом случае они пропадут из панели ToolBox.

Шаг третий. Добавляем компонент для отрисовки диаграмм/графиков Chart в проект WPF

Для того чтобы добавить элемент Chart в проект, необходимо его перетащить на форму, после чего сохранить проект. Обращаем внимание, что в разделе References добавилась новая ссылкаSystem.Windows.Controls.DataVisualization.Toolkit.

chart c visual studio

После того, как проект сохранен, можно открыть его в Blend Studio 4.0 для продолжения работы над интерфейсом (при этом Chart уже будет доступен на панели Controls), либо продолжить разработку в Visual Studio 2010.

Построение графиков является ключевой частью рабочего процесса обработки и анализа данных. В инструментах R для Visual Studio (RTVS) все действия по построению графиков сосредоточены в одном или нескольких окнах графиков, которые призваны повысить эффективность работы специалистов по анализу и обработке данных с помощью этого ключевого действия.

Изображение с параметрами построения графиков

Окно графиков

В окне находится ряд графиков, каждый из которых генерируется командой plot . Например, команда plot(1:100) позволяет создать новое окно графиков, если его еще нет.

Линейный график от 1 до 100

Говоря техническим языком, команды plot в R преобразуют свои выходные данные и передают их на графическое устройство R; окна графиков выполняют отрисовку контента графического устройства , поэтому каждому окну графиков присваивается отдельный номер устройства.

Окна графиков не зависят от проектов Visual Studio и остаются открытыми по мере загрузки и закрытия проектов.

Для создания графика используется "активное" окно графиков, а предыдущий график сохраняется в журнале графиков (см. подраздел Журнал графиков). Например, введите plot(100:1) , и первый график заменяется направленной вниз прямой линией.

Как и во всех других окнах Visual Studio, в окне графиков поддерживаются настраиваемые макеты (см. раздел Настройка макетов окон в Visual Studio). Окно графиков можно закрепить в любом месте окна Visual Studio, изменить его размер в рамках этого окна, а также извлечь его из окна Visual Studio и изменить его размер.

При изменении размеров окна графиков график всегда перестраивается для достижения наилучшего качества изображения. Обычно изменить размер требуется перед экспортом графика в файл или в буфер обмена с помощью команд, описанных в следующем разделе.

Команды для работы с окном графиков

На панели инструментов окна графиков находятся соответствующие команды, большинство из которых также доступны в меню Инструменты R > Графики.

Несколько окон графиков

Так как во время обработки и анализа данных часто приходится работать с несколькими графиками, построенными на основе различных наборов данных, RTVS позволяет создать любое количество отдельных окон графиков. Затем их можно упорядочить любым требуемым образом как внутри окна Visual Studio, так и за его пределами. (Общие сведения о закреплении и изменении размеров окон см. в разделе Настройка макетов окон в Visual Studio.)

Создать окно графика можно с помощью соответствующей кнопки на панели инструментов или воспользовавшись командой Инструменты R > Графики > Создать окно графиков. Новое окно графиков становится активным окном, где выполняется построение новых графиков. Чтобы изменить активное окно, переключитесь на нужное окно и нажмите на панели инструментов кнопку Активировать окно графиков или воспользуйтесь командой Инструменты R > Графики > Активировать окно графиков.

Графики представляют собой независимые объекты. Это означает, что их можно копировать или перемещать между окнами графиков с помощью функции перетаскивания мышью или с помощью команд Копировать, Вырезать и Вставить в контекстном меню и в меню Правка.

По умолчанию при перетаскивании мышью выполняется копирование графика; для перемещения при перетаскивании следует удерживать нажатой клавишу SHIFT.

Журнал графиков

Команды построения сохраняются в журнале графиков для каждого окна, обеспечивая сохранность всех операций построения в течение сеанса работы с графиком. Чтобы просмотреть журнал, используйте кнопки со стрелками на панели инструментов окна графиков или клавиши CTRL+ALT+F11 и CTRL+ALT+F12. Можно также удалить отдельные графики или очистить все графики в окне, воспользовавшись для этого кнопками на панели инструментов или командами меню Инструменты R > Графики.

Для просмотра всей коллекции графиков откройте окно журнала графиков с помощью соответствующей кнопки на панели инструментов или команды Инструменты R > Графики > Окно журнала графиков. Будет представлен список эскизов графиков, которые были построены в этом окне, сгруппированных по разным окнам графиков (или по устройствам). С помощью кнопок масштабирования на панели инструментов можно изменить размеры эскизов.

Окно журнала графиков

Чтобы открыть график в соответствующем окне, дважды щелкните нужный график, выберите его, а затем нажмите на панели инструментов кнопку Показать график или щелкните правой кнопкой мыши и выберите команду Показать график. Можно также выбрать отдельный график и скопировать, вырезать или удалить его, выбрав соответствующую команду в контекстном меню или в меню Правка.

Время существования журнала графиков во всех окнах привязано ко времени существования сеанса работы с интерактивным окном R. Если сбросить сеанс R или выйти и перезапустить Visual Studio, журнал графиков сбрасывается.

Программное управление окнами графиков

Управлять окнами графиков можно программным способом с помощью кода R, используя номера устройств для идентификации отдельных окон графиков.

Аннотация: Весь изложенный материал, без особого труда, можно найти в MSDN и сети, но для большинства статей характерен уход в вопросы, которые затрудняют создание четкого и ясного представления о том, как работать с графикой. При решении корпоративной задачи вывода графиков в Web приложении, автору сначала потребовалось обобщить материал, и, лишь после того, приступить собственно к выполнению задания. Материалы этого обобщения и приводятся в данной статье.

PS: Материал первоначально касался только отображения графики на Web страницах, но поступающие от читателей вопросы по использованию графики в Windows стали причиной дополнения данного материала еще одной главой, которую, в силу методических соображений, автор поместил первой.

Глава 1. Использование графики в Windows приложениях

Параграф 1. Где и как возможно отображать графическую информацию в Windows приложениях

В Visual Studio Net нет стандартных средств для создания графиков, диаграмм. Поэтому, большинство статей на рассматриваемую тему рекомендуют использовать Office Web Components (OWC) - компонент Windows для построения диаграмм в Web. Как достоинство этого подхода обычно отмечается простота построения графиков и диаграмм и интуитивно близкие задания параметров графической информации с их заданием при использовании графики в MS Office. Но простота не всегда достоинство, когда мы строим график "под себя". Да и достаточно для программиста сомнительна, когда он однажды создав код графического класса, он всегда легко и быстро может его перенастроить его для конкретной задачи, не влезая в дебри некого универсального кода, где порой гораздо больше времени будет затрачено на уяснение параметров и задание их значений и границ. Поэтому, речь далее пойдет о создании собственных графиков с "чистого листа". Основные типы графиков, которые будут рассмотрены, по мнению автора, могут стать достаточными для большинства практических задач и базой для дальнейших собственных разработок.

В Microsoft Windows существует несколько средств для вывода графической информации, включая DirectDraw, OpenGL, GDI и т.д. Мы будем использовать Graphics Device Interface (GDI, более поздние версии GDI+) - подсистему Windows, ответственную за вывод графики и текста на дисплей и принтер. Именно CGI+ обеспечивает вывод на экран всего того, что видит пользователь Windows в окне монитора. GDI+ является базовым способом вывода графики в Windows.

Рассмотрим простейшие примеры. Создадим решение Windows приложения с одной кнопкой и следующим обработчиком ее нажатия:

Результат вывода при нажатии кнопки 1, показан на Рис.1:

Рис.1. Создание и использование объект класса Graphics на основе битовой матрицы

Одинакового эффекта (Рис.1.), можно добиться, если использовать обработчики некоторых событий, которым передается объект класса Graphics как аргумент (например, обработчик события Paint формы приложения):

Одинакового эффекта (Рис.1.), можно добиться и при непосредственном создании объекта Graphics:

А так можно рисовать (писать) на кнопке и на других контролах, для которых может быть создан обработчик события Paint (Рис.2.):

Класс Graphics находятся в пространстве имен Drawing (хотя, забегая вперед, нам понадобится и пространство имен Drawing.Drawing2D, по сему, целесообразно сразу добавить их в решение).

SolidBrush - сплошная закраска цветом кисти;

TextureBrush - наложение картинки (image) на область закраски;

HatchBrush - закраска области предопределенным узором;

LinearGradientBrush - сплошная закраска c переходом цвета кисти (градиентная закраска);

Пример использования конструктора HatchBrush показан на Рис.2.:

Рис.2. Пример использования конструктора HatchBrush

Как видно из приведенных примеров, существует несколько способов отображение графики. Основное их отличие - при использовании битовой матрицы и свойств контролов изображение рисуется один раз и не исчезает (нет необходимости его вновь рисовать) при перерисовки формы.

Здесь нет необходимости подробно описывать все методы объекта Graphics, их можно легко увидеть из контекстной подсказки, как обычно, поставив точку после написания имени объекта. По этой же причине нет необходимости перечислять и преопределенные цвета карандашей (Color.) и кистей (Brushes.)

Круговые фигуры рисуются при указании в качестве стартовой точки левого верхнего угла (см. последний пример);

Рисование непосредственно на форме не всегда является и не есть хороший тон, кода Visual Studio предлагает специальный контрол, который, как нельзя лучше, подходит для вывода графической информации и обладает всеми преимуществами контролов: программное позиционирование и масштабирование без перерисовки формы, возможность выполнять Stretch Image и множество других полезных свойств и событий. Кроме того простой доступ к Graphics, аналогично через событии Paint и возможность использования битовых карт Bitmap для создания объекта Graphics, с последующим переносом их в контрол (аналогично, как мы делали это в первом примере):

Далее мы будем использовать именно PictureBox, как объект для отображения графической информации.

Параграф 2. Создание линейных графиков

2.1. В качестве постановки задачи

Однажды мне пришлось делать задачку, на базе продолжения работы над которой появилась программа "LitFrequencyMeter" - программа определения частоты повторения слов и знаков в литературных произведениях, графики из которой приведены ниже (Рис.3-5.). И когда я приступил к заключительному этапу работы над программой, то понял, что материал главы практически написан в кодах - осталось только его озвучить.

Настройка всего и вся: цветов, шрифтов, фонов, надписей, положения диаграмм на холсте, использование пояснений, легенд, смена числа отсчетов и т.д., и т.п.

Хранение всех настроек (включая шрифты) в реестре.

В данной статье подробно рассмотрен первый аспект - как строить графики, приведенные ниже. Чтобы было понятно, что отображено на графиках - приведу полный текст отрывка (надеюсь, он всем знаком с детства):

Далее результаты анализа в графическом виде (программа представляет и текстовый вариант анализа, но он нам на данном этапе не нужен).

Рис.3. Линейеая диаграмма

Рис.5. Круговая диаграмма

2.2. Постановка задачи

Стоит задача создать класс для отображения графической информации, который бы мог стать базовым классом для работы с графикой, позволял бы не только выводить различные виды графиков и обладал бы гибкостью настройки форм отображения, но и оставался открытым для дальнейшего его расширения.

Конечная цель - помещение созданного графического изображения в элемент управления PictureBox.

2.3. Исходные данные

Исходные данные перед их отображением могут находиться где угодно (файл, таблица базы данных. ). Однако рассматривать чтения из базы данных или из файла значений графиков - только засорять отображение материала. Мы всегда можем прочитать данные с любого источника в массив значений. Автор предпочитает работать со строковым массивом, как позволяющим хранить цифровые и текстовые значения. В примерах, приводимых ниже, используется массив строк string[,] rgsValues. В программе, о которой шла выше речь, этот массив использован для настройки параметров, отображаемых на графике. Заполнять массив будем с помощью датчиков случайных чисел:

Предполагается, что значение переменной, определяющий размерность массива хранится в настройках и устанавливается на этапе загрузки приложения.

2.4. Проект решения

Создадим простой проект WindowsApplication решения с любым именем (у меня graph1). Поместим на форму три кнопки, в свойствах "Текст" которых напишем соответственно: "Линейная диаграмма", "Гистонрамма" и "Круговая диаграмма". Ниже кнопок поместим контрол PictureBox. Подберем удобное для себя расположение кнопок и PictureBox (в реальных программах для размещения удобнее использовать контролы TableLayoutPanel, но сейчас нас интересует графика, а не размещение).

В окне Solutation Explorer кликаем правой кнопкой мышки на узле решения (у меня graph1) и в контекстном меню выбираем Add\New Item. В окне Templates выбираем Class, даем ему имя, например PaintCl.cs и нажимаем кнопку Add. Будет создан пустой класс.

Нашей задачей будет постепенное наполнение этого класса при минимуме добавления кода в основной файл кода приложения - Form1.cs.

Для начала создадим обработчик события нажатия кнопки "Линейный график" (клик мышкой на кнопке), а также обработчики для событий Load и FormClozed (первый можно кликом мышки на форме, второй через окно Properties формы - закладка Events - клик в окошечке против события FormClosed). Слегка преобразуем код, как показано ниже:

Назначение переменной viNumButton, будет ясно далее. Массив значений у нас создан. Осталось нарисовать по значениям массива график, используя класс.

2.5. Конструкторы класса

Начало класса - конструктор и закрытые переменные. В классе лучше иметь несколько конструкторов. Например, таких как приведено в коде ниже. И, естественно, необходимо сразу определить основные объекты для графики: битовую матрицу, объект Graphiks, шрифт, кисть и перо (о чем мы говорили выше), а также переменные для сохранения размеров холста:

Пустой конструктор, как правило, ничего не дает и потребует в дальнейшем введения дополнительных функций для инициализации объектов отображения графики. Для нашей цели он не удобен и мы можем его вычеркнуть (не использовать). Однако если мы, например, захотим передавать в качестве объекта для рисования некоторый рисунок, то вынуждены будем воспользоваться или новым сложным конструктором или добавить в класс всего лишь функцию передачи рисунка, так как функции инициализации объектов рисования так или иначе у нас уже будут. И, хотя, нагрузка на конструктор при инициализации основных объектов не страхует от необходимости иметь функции переопределения параметров объектов рисования, все же второй конструктом мне кажется более предпочтительным.

2.6. Создаем объект для рисования

Используем второй конструктор и создадим и инициализируем в классе сразу все объекты, которые нам необходимы:

Таким образом, нам понадобятся в классе еще две функции: установки фона холста и приема изображения из класса. Добавим их в класс:

Выполним решение на данном этапе. Результат показан на Рис.6.:

Рис.6. Взаимодействие кода формы с кодом класса

В принципе, описанный выше код показал сам принцип создания изображения с использованием PictureBox и создаваемого нами и претендующего на универсальность класса для рисования графиков.

2.7. Рисуем оси

Добавим в классе переменные для хранения отступов от краев холста (они нам еще понадобятся не один раз).

Добавим функцию рисования осей и функции запоминания цвета и толщины осей. Функция выполняет простую задачу - рисует две линии и при необходимости стрелочки на конце осей:

Осталось добавить вызов функции рисования осей:

В функции vDravAxis мы задали параметры непосредственно. Отметим еще раз, что все величины целесообразно иметь настраиваемыми и их значения хранить в реестре.

Рис.7 Рисование осей линейного графика

2.8. Рисуем сетку

Для рисования сетки нам потребуется: цвет и толщина пера, размер массива отображаемых значений и непосредственно функция для рисования сетки. Установку цвета и толщины пера мы уже использовали при рисовании осей, поэтому в функции vCreateLinGr() добавим вновь вызовы:

Для хранения размера массива в классе определим переменную и определим доступ к ней через свойство, а также определим функцию, рисующую сетку viMaxRg*viMaxRg клеток. Рисование сетки сводится к рисованию параллельных осям линий:

В функции vCreateLinGr() добавим код и выполним решение:

Результат показан на Рис.8.:

Рис.8. Рисование сетки

2.8. Рисуем линию графика

Как мы уже делали - зададим цвет и толщину пера. Далее нам понадобятся данные из нашего массива значений непосредственно в классе. Для этого в классе определим массив и доступ к нему:

В классе создадим функцию рисования линий графика. Линии рисуются по соседним точкам массива:

Код vCreateLinGr() на данный момент:

Результат выполнения решения на данном этапе показан на Рис.9.:

Рис.9. Рисование линий графика

2.10. Надписи на графике

Надписи можно наносить по оси Х, по оси Y и над точками линий графика. Причем иногда бывает целесообразно выполнять соседние надписи со сдвигом по оси Y. Кроме того - надписи выполняются не пером, а кистями и требуют задания шрифта. Таким образом, перед выполнением надписей надо установить в классе соответственно шрифт и кисть (Brush).

Для передачи шрифта и кисти создадим в классе свойства:

В функции рисования графика запишем код:

Для выполнения различных надписей создадим в классе несколько функций. Подробно давать пояснения нет необходимости. Здесь, как и при рисовании линий, необходимо постоянно рассчитывать дельны расстояний по осям и точки начала надписей.

Мы создали полностью код для отображения линейного графика. Все функции для управления построением и изменения внешнего вида представлены в void vCreateLinGr():

Результат выполнения кода показан на Рис.10.:

Рис.10. Линейный график

Параграф 3. Создание гистограмм

Для построения гистограмм нам потребуется внести в наш класс одну новую функцию и один массив переменных Brush. Можно было воспользоваться классом SolidBrush и по датчику случайных чисел формировать цвета, но все же, более приятно смотреть гистограмму с удачно подобранными соседними цветами (каждый может выполнить подборку цветов на свой вкус).

И так, нам понадобится всего лишь одна новая функция. Основное отличие - использование функции FillRectangle.

Запишем код обработки нажатия кнопки 2 и выполним решение:

Цветом показано единственное отличие от кода создания линейной диаграммы. Результат работы кода приведен на Рис.11.:

Параграф 4. Круговые диаграммы и элементы 3D графики

Построение круговых диаграмм с элементами 3D графики требует несколько больших затрат по сравнению с рассмотренным выше материалом. Прежде всего, необходимо определить дополнительные переменные для величин: оси эллипса (vfDiamX, vfDiamY), центр круговой диаграммы (vfXcirc, vfYcirc). Кроме того, если мы хотим, что бы в легенде (пояснению к графику) цвета надписей соответствовали цветам секторов диаграммы, то потребуется задать массив цветов однозначно соответствующий массиву цветов кистей. Зададим в классе:

Основная функция для рисования диаграммы имеет ряд особенностей, связанных с формированием объемности и расположением надписей.

Первый этап: Против часовой стрелки рисуем последний сектор и сектора, выходящие за границу 180 градусов, но не заходящие за границу 270 градусов. Рисовать будем кистью с прозрачностью, например 25%, и каждый из них со сдвигом на 1 пиксель вниз. Иначе, если толщина диаграммы задана 20 пикселей, то сектор потребуется нарисовать 20 раз, каждый раз сдвигая на 1 пиксель вниз (Рис.12.1.).

Рис.12.1. Первый этап создания круговой диаграммы

Второй этап: Накладываем на данную диаграмму сектора от 0 градусов до сектора, заходящего за 270 градусов, используя SolidBrush и не выполняя сдвиг - рисуем каждый сектор один раз из точки рисования всей диаграммы (Рис.12.2.).

Рис.12.2. Второй этап создания круговой диаграммы

Третий этап: по часовой стрелки рисуем сектора, начиная со второго, используя HatchBrush. Рисование выполняем до сектора заходящего за границу -90 градусов, со сдвигом на толщину диаграммы (Рис.12.3.).

Рис.12.3. Третий этап создания круговой диаграммы

Четвертый этап: По часовой стрелке накладываем без сдвига, начиная со второго сектора до сектора, заходящего за границу -90 градусов, используя SolidBrush (Рис.12.4.).

Рис.12.4. Четвертый этап создания круговой диаграммы

Отдельно рисуем первый сектор, сначала используя HatchBrush со сдвигом на толщину диаграммы, затем накладываем сектор SolidBrush без сдвига. Координаты сектора определяем с учетом параметров сдвига секторов (Рис.12.5.).

Алгоритм рисования можно упростить, например, один раз и последним этапом наложить сектора эллипса, нарисованный кистью SolidBrush, но, в этом случае пострадает наглядность.

Эти этапы рисования выполняет следующая функция:

Добавляем функции надписи и легенду и, в принципе, построение диаграммы закончено. Единственное, что потребуется от нас при рисовании надписей на диаграмме - это немного вспомнить начальную школу при расчете координат нанесения значений:

Оформим вызовы функций:

Отметим, что при задании толщины диаграммы, равной нулю, получим обычную эллиптическую диаграмму, а при равенстве осей Х и Y - круговую.

Результат выполнения решения показан на Рис.12.6:

Рис.12.6. Круговая диаграмма

В заключении, еще раз повторим, что все параметры целесообразно иметь настраиваемыми, что позволяет быстро подобрать приемлемый вид графического отображения для демонстрации. Целесообразно также выполнить автономную настройку диаграмм по тестовым значениям (как это сделано в программе LitFregMeter - см. Параграф 2.). Тогда мы сможем быстро подбирать параметры, например так:

Параграф 5. Базовый класс для рисования графиков

В заключении главы приводим полностью класс, созданный нами. Вы его можете без труда не только использовать в своих приложениях, но и развивать дальше - включая новые типы диаграмм.

Автор будет благодарен, если кто сможет дополнить класс новыми типами графиков, и пришлет по почте. Любые интересные Ваши находки будут помещены (включены) в данный материал с указанием Вашего участия (авторства).

Молчанов Владислав 21.09.2005г. Материал переработан 14.10.2008г.

Используя данный пример, можно создавать собственные программы для построения графиков других функций. По желанию можно модернизировать работу программы по своему усмотрению.

Содержание

Поиск на других ресурсах:

Условие задачи

Задана формула функции двух переменных z = sin(x) + cos(y) . Разработать приложение, которое рисует график этой функции в отдельной форме.

Дополнительно реализовать поворот графика влево, вправо, вверх, вниз. Также нужно выводить оси OX , OY , OZ .

Математическая постановка задачи

Построение графика функции двух переменных есть математически решаемой задачей, в которой используются известные формулы вычисления.

График функции двух переменных z(x,y) строится в параллелепипеде с размерами (xx1, xx2) , (yy1, yy2) , (zz1, zz2) .

Для использования поворота системы в 3-мерном пространстве возникает понятие точки ( x0 , y0 , z0), относительно которой происходит поворот системы координат.

Также возникает понятие углов:

    (альфа) – поворот системы относительно оси OZ ; (бета) – поворот системы относительно оси OX .

Сдвиг в точку ( x0 , y0 , z0 ) с учетом поворота на углы и описывается известными соотношениями

Преобразования координат 3D Формулы

После перемножения матриц получаем формулу для вычисления:

02_02_00_013_formula_02

По этой формуле будет происходить преобразование системы координат и масштабирование (рисунок 1).

Рисунок. Сдвиг и поворот системы координат

Рис. 1. Сдвиг и поворот системы координат

Необходимо определиться, в какой плоскости монитора будут лежать оси координат OX , OY , OZ . Принимаем, что в плоскости монитора лежат оси OX и OY . А ось OZ перпендикулярна экрану.

Координаты расчетной точки (x, y) прижимаются к точке (0, 0) по формулам:

где A , a – коэффициенты перспективы, которые подбираются экспериментально в зависимости от функции.

Выполнение

1. Создание проекта как Windows Forms Application

2. Создание формы Form1 .

Создать форму по образцу, как показано на рисунке 2.

Настроить следующие свойства компонент и формы:

3. Создание формы Form2 .

Создать новую форму. Подробный процесс создания новой формы описывается здесь .

Разместить на форме четыре компонента типа Button. Автоматически создается четыре объекта с именами button1, button2, button3, button4.

Настроить свойства компонент и формы следующим образом:

Приблизительный вид формы Form2 изображен на рисунке 3.

4. Ввод внутренних переменных в форму Form2 .

Все внутренние переменные, использующиеся для организации вывода графика, размещаются в классе формы Form2. Поэтому, сначала надо активизировать модуль « Form2.pas ».

В модуль формы Form2 вводятся следующие внутренние переменные с классом видимости private:

  • xx1, xx2, yy1, yy2 – соответствуют координатам точек, которые отображаются на экране монитора;
  • массивы xx и yy предназначены для вывода плоскости из 4-х точек. Область определения функции z = f(x, y) разбивается на прямоугольники, на любом из которых функция экстраполируется ребрами четырехугольника.

В разделе public вводятся:

  • переменные X_min , Y_min , X_max , Y_max вещественного типа, которые представляют реальные координаты параллелепипеда, в котором выводится график функции. Эти переменные заполняются из основной формы Form1 экспериментальным путем:
  • переменные alfa, beta вещественного типа, которые отображают углы наблюдения за графиком функции. Заполняются из главной формы Form1;
  • переменные x0, y0, z0 вещественного типа. Отображают величины из главной формулы вычисления (см. математическую постановку задачи);
  • переменная A вещественного типа. Представляет коэффициент перспективы и подбирается экспериментально;
  • переменная f_show логического типа используется для указания того, что нужно перерисовать график, в случае изменения положения углов alfa и beta.

После введения переменных в текст программы, фрагмент класса формы Form2 имеет вид:

Переменные, имеющие идентификатор доступа public, заполняются из формы Form1 .

5. Программирование внутренних методов в форме Form2 .

В текст класса Form2 вводятся три дополнительных метода:

  • функция преобразования системы координат и масштабирования Zoom_XY() ;
  • функция func() для которой выводится график;
  • функция рисования графика Show_Graphic().

Листинг метода преобразования системы координат следующий:

Листинг метода func() следующий.

В этом методе вместо строки

можно сделать вставку собственной функции.

Непосредственный вывод графика функции реализован в методе Show_Graphic() . Листинг метода Show_Graphic() следующий.

Объясним некоторые фрагменты кода в методе Show_Graphic().

Область определения функции z = f(x,y) разбивается на прямоугольники, на любом из которых функция экстраполируется с ребрами четырехугольника. Построение четырехугольников на экране реализуется с помощью метода DrawLine().

После очистки канвы происходит рисование осей координат и методом DrawLine() выводятся фрагменты поверхности.

При рисовании поверхности, из метода Show_Graphic() вызывается метод Zoom_XY(), что осуществляет преобразование и масштабирование из реальных координат в экранные координаты.

6. Программирование события Paint формы Form2.

Обработчик события Form2_Paint() получает два параметра. Первый параметр типа System.Object , второй параметр типа PaintEventArgs .

Параметр типа PaintEventArgs содержит объект Graphics, необходимый для рисования на поверхности формы.

Листинг обработчика события Form2_Paint() следующий.

7. Программирование обработчиков событий клика на кнопках button1, button2, button3, button4.

Поворот графика происходит в момент, когда пользователь делает клик на одной из кнопок, размещенных на форме Form2 (элементы управления button1, button2, button3, button4).

Отображение графика зависит от внутренних переменных alfa и beta. Переменная alfa содержит угол поворота относительно оси OZ . Переменная beta содержит значение угла поворота вокруг оси OX .

Поэтому, в обработчиках событий происходит изменение значений alfa и beta на некоторую величину. По желанию, можно установить собственную величину изменения alfa и beta.

Листинг обработчиков событий приведен ниже.

В вышеприведенных обработчиках событий, событие Paint генерируется явно с помощью унаследованного метода Invalidate(). Этот метод делает перерисовывание всей клиентской области программным путем.

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

8. Программирование обработчиков событий MouseDown, MouseMove и MouseUp.

Для осуществления поворота графика с помощью мышки нужно запрограммировать соответствующие обработчики событий.

Если нажать клавишу мыши и удерживать ее нажатой над формой Form2, а потом отпустить, то генерируются такие события (рисунок 4):

  • MouseDown – генерируется, если пользователь делает клик мышкой на форме Form2;
  • MouseMove – генерируется, если пользователь перемещает мышку над формой Form2 (независимо, нажата ли одна из кнопок мышки);
  • MouseUp – генерируется, если пользователь отпускает кнопку мышки после нажатия.

9. Листинг модуля « Form2.cs ».

Ниже приведен полный текст файла ” Form2.cs ”, который соответствует форме Form2.

10. Программирование события клика на кнопке button1 формы Form1 (вызов формы рисования графика функции).

При клике на кнопке button1 из формы Form1 может выводиться график функции.

Обработчик события клика на кнопке Button1 имеет вид.

11. Запуск программы.

После запуска программы на выполнение, форма графика функции изображена на рисунке 5.

Читайте также: