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




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

Что и какие аспекты были заложены в программу:

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

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

3. Создание статистики из.txt,.html,.doc файлов.

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

сказка о царе салтане,

о сыне его славном и могучем богатыре

князе гвидоне салтановиче и

о прекрасной царевне лебеди

три девицы под окном

пряли поздно вечерком.

" кабы я была царица, -

говорит одна девица, -

то на весь крещеный мир

приготовила б я пир ".

- " кабы я была царица, -

говорит ее сестрица, -

то на весь бы мир одна

наткала я полотна ".

- " кабы я была царица, -

третья молвила сестрица, -

я б для батюшки - царя

родила богатыря ".

только вымолвить успела,

дверь тихонько заскрыпела,

и в светлицу входит царь,

стороны той государь.

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

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

Рис.4. Гистограмма

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

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

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

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

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

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

private int viNumInRg=20;//20 - начальное значение

private string[,] rgsValues=null;

 

private int iCreateRg()

{

Random rnd = new Random(DateTime.Now.Millisecond);

Random rnd1 = new Random(DateTime.Now.Millisecond+5);

rgsValues = new string[viNumInRg, 2];

for (int i = 0; i < viNumInRg; i++)

{

rgsValues[i, 0] = Convert.ToString(((float)(rnd.Next(0, 10) * 100) +

(float)rnd1.Next(0, 99)) / (float)100);

rgsValues[i, 1] = "I-" + Convert.ToString(i+1);

}

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

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

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

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

using System;

using System.Collections.Generic;

using System.Text;

namespace graph1

{

class PaintCl

{

}

}

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

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

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

namespace graph1

{

public partial class Form1: Form

{

private int viNumButton = 0;

private int viNumInRg=20;//20 - начальное значение

private string[,] rgsValues=null;

 

public Form1()

{

InitializeComponent();

}

 

 

private void Form1_Load(object sender, EventArgs e)

{

//Здесь при создании реальной программы необходимо

//будет предусмотреть восстановление сохраненных

//параметров для приложения и графиков

}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)

{

//Здесь при создании реальной программы необходимо

//будет предусмотреть сохранение параметров

//для приложения и графиков

}

 

 

#region Создание массива значений

private void vCreateRg()

{

Random rnd = new Random(DateTime.Now.Millisecond);

Random rnd1 = new Random(DateTime.Now.Millisecond+5);

rgsValues = new string[viNumInRg, 2];

for (int i = 0; i < viNumInRg; i++)

{

rgsValues[i, 0] = Convert.ToString(((float)(rnd.Next(0, 10) * 100) +

(float)rnd1.Next(0, 99)) / (float)100);

rgsValues[i, 1] = "I-" + Convert.ToString(i+1);

}

}

#endregion

 

#region создание линейного графика

private void button1_Click(object sender, EventArgs e)

{

viNumButton = 1;

vCreateLinGr();

}

private void vCreateLinGr()

{

//Создаем массив значений для вывода на графике

vCreateRg();

 

}

#endregion

}

}

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

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

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

using System;

using System.Collections.Generic;

using System.Text;

using System.Drawing;

using System.Drawing.Drawing2D;

namespace graph1

{

class PaintCl

{

//Основные объекты для рисования

private Bitmap bmp = null;

private Graphics graph = null;

private Font objFont = new Font("Arial", 8, FontStyle.Bold);

private Brush objBrush = Brushes.Black;

private Pen objPenLine = new Pen(Color.Black, 1);

//Размеры холста

private int viX = 200;

private int viY = 100;

 

#region Конструкторы

//Первый

public PaintCl()

{

 

}

//Второй

public PaintCl(int a, int b)

{

bmp = new Bitmap(a, b);

//Создаем объект Graphics на основе битовой матрицы

graph = Graphics.FromImage(bmp);

//Запоминаем размеры холста

viX = a;

viY = b;

}

#endregion

}

}

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2020-11-01 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: