На этом шаге мы рассмотрим параметры и использование линии.
Метод DrawLine рисует прямую линию. В инструкции вызова метода следует указать карандаш, которым надо нарисовать линию, и координаты точек начала и конца линии:
DrawLine(aPen, x1, y1, x2, y2)
DrawLine(aPen, p1, p2)
Параметр aPen (типа Brush) задает карандаш, которым рисуется линия, x1 и y1 или p1 - точку начала линии, а x2 и y2 или p2 - точку конца линии. Параметры x1, y1, x2 и y2 должны быть одного типа (Integer или Single). Тип параметров p1 и p2 - Point.
Например, инструкция
e->Graphics->DrawLine(Pens::Green,10,10,300,10);
Эту же линию можно нарисовать и так:
Point p1 = Point(10,10); Point p2 = Point(300,10); e->Graphics->DrawLine(Pens::Green, p1, p2);
Программа "График" (ее окно приведено на рисунке 1) показывает использование метода DrawLine. Данные, отображаемые в окне программы, загружаются из текстового файла.
Рис.1. Программа "График"
Загружает данные из файла конструктор формы (файл данных usd.dat должен находиться в папке приложения, при запуске программы в режиме отладки из среды разработки - в папке Debug). Он же выполняет обработку массива данных - ищет минимальный и максимальный элементы ряда. Конструктор также, в случае успешной загрузки данных, задает функцию обработки события Paint формы. Непосредственно вывод графика на поверхность формы выполняет функция drawDiagram. Ее вызывает функция обработки события Paint формы, а также косвенно (путем вызова метода Refresh) - функция обработки события Resize формы.
// конструктор Form1(void) { InitializeComponent(); // //TODO: добавьте код конструктора // // чтение данных из файла в массив System::IO::StreamReader^ sr; // поток для чтения try { sr = gcnew System::IO::StreamReader(Application::StartupPath + "\\usd.dat"); // создаем массив d = gcnew array<double>(10); // читаем данные из файла int i = 0; String^ t = sr->ReadLine(); while ((t != String::Empty) && (i < d->Length)) { // записываем считанное число в массив d[i++] = Convert::ToDouble(t); t = sr->ReadLine(); } // закрываем поток sr->Close(); // определить минимальное и максимальное значения ряда min = d[0]; max = d[0]; for (int i = 1; i < d->Length; i++) { if (d[i] > max) max = d[i]; if (d[i] < min) min = d[i]; } // Данные загружены. // Задаем функцию обработки события Paint this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &Form1::drawDiagram); } // Обработка исключений: файл данных не найден catch (System::IO::FileNotFoundException^ ex) { MessageBox::Show(ex->Message + "\n", "График", MessageBoxButtons::OK, MessageBoxIcon::Error); } } . . . . . . private: array<double>^ d; // ряд данных double max; // максимальный элемент массива double min; // минимальный элемент массива // строим график void drawDiagram(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { // графическая поверхность System::Drawing::Graphics^ g = e->Graphics; // шрифт подписей данных System::Drawing::Font^ dFont = gcnew System::Drawing::Font("Tahoma", 9); // шрифт заголовка System::Drawing::Font^ hFont = gcnew System::Drawing::Font("Tahoma", 13, FontStyle::Regular); String^ header = "Изменение курса доллара"; // ширина области отображения текста int wh =(int)g->MeasureString(header, hFont).Width; int x = (this->ClientSize.Width - wh) / 2; g->DrawString(header,hFont, Brushes::DarkGreen, x, 5); /* Область построения графика. Отступы: сверху - 100; снизу - 20; слева - 20; справа - 20. ClientSize - размер внутренней области окна График строим в отклонениях от минимального значения ряда данных так, чтобы он занимал всю область построения */ // рисуем график int x1, y1, x2, y2; // расстояние между точками графика (шаг по Х) int sw = (int)((this->ClientSize.Width - 40) / (d->Length - 1)); // первая точка x1 = 20; y1 = this->ClientSize.Height - 20 - (int)((this->ClientSize.Height - 100) * (d[0] - min) / (max - min)); // маркер первой точки g->DrawRectangle(Pens::Black, x1 - 2, y1 - 2, 4, 4); // подпись численного значения первой точки g->DrawString(Convert::ToString(d[0]), dFont, Brushes::Black, x1 - 10, y1 - 20); // остальные точки for (int i = 1; i < d->Length; i++) { x2 = 8 + i * sw; y2 = this->ClientSize.Height - 20 - (int)((this->ClientSize.Height - 100) * (d[i] - min) / (max - min)); // маркер точки g->DrawRectangle(Pens::Black, x2 - 2, y2 - 2, 4, 4); // соединим текущую точку с предыдущей g->DrawLine(Pens::Black, x1, y1, x2, y2); // подпись численного значения g->DrawString(Convert::ToString(d[i]), dFont, Brushes::Black, x2 - 10, y2 - 20); x1 = x2; y1 = y2; } } private: System::Void Form1_Resize(System::Object^ sender, System::EventArgs^ e) { this->Refresh(); }
На следующем шаге мы рассмотрим ломаную линию.