Рассмотрим основные принципы построения гистограмм на примерах построения гистограммы и круговой диаграммы. Интерактивность в данном случае обеспечивается данными в файле.
Пример 15.3. Создать проект, в котором необходимо построить гистограмму по данным из массива из n элементов. Значения элементов массива считать из текстового файла. Текстовый файл поместить в папку Win32\Debug. В этом случае для доступа к файлу достаточно прописать имя файла. Если файл хранится в другом месте, то для доступа к файлу необходимо прописать полный путь.
Этапы выполнения задания
- Поместить на форму компоненты: изображение (Image) и кнопка (Button).
- Изменить свойства Caption у компонента Button1 на «Построить».
- Установить размеры Image — 600 × 400.
- Написать обработчик события OnClick для компонента Button1, в котором диаграмма строится с помощью прямоугольников.
4.1. Считать данные из файла в массивы: массив d — хранит числа, по которым строится диаграмма; массив s — подписи элементов. Для работы с файлами подключить библиотеку <fstream>. Для чтения строк из файла подключить библиотеку <string>, для работы с. массивами — библиотеку <vector>. Прописать директиву Using NameSpace std для обращения к командам стандартных библиотек. 4.2. Найти максимальный элемент в массиве — элемент, стоящий на месте n_max. 4.3. Рассчитать масштабный коэффициент: . Для того чтобы оставить место для вывода надписей, от высоты формы отнимаем 40. 4.4. В цикле строить n прямоугольников одинаковой ширины. Ширина прямоугольника — Высота прямоугольника определяется значением , преобразованным к целому типу. Цвет прямоугольников задавать случайно — каждая составляющая цвета изменяется в диапазоне от 1 до 245 (исключаем черный цвет и цвета близкие к белому). 4.5. Вывести надписи над прямоугольниками. Для вывода строк, считанных из файла, их нужно преобразовать так, чтобы можно было вывести на канву. Для этого можно воспользоваться функцией c_str().
Пример 15.4. Создать проект, в котором нужно построить круговую диаграмму по данным из массива. Значения элементов массива считать из текстового файла. Текстовый файл поместить в папку Win32\Debug.
- Поместить на форму компоненты: изображение (Image) и кнопка (Button).
- Изменить свойства Caption у компонента Button1 на «Построить».
- Установить размеры Image — 500 × 500.
- Для работы с файлами подключить библиотеку <fstream>. Для чтения строк из файла подключить библиотеку <string>, для работы с массивами — библиотеку <vector>. Для вычислений понадобятся тригонометрические функции, поэтому необходимо подключить библиотеку <cmath>. Прописать директиву using namespace std для обращения к командам стандартных библиотек.
- Написать обработчик события OnClick для компонента Button1, в котором диаграмма строится с помощью секторов.
5.1. Считать данные из файла в массив. 5.2. Найти сумму элементов массива — sum. 5.3. Рассчитать масштабный коэффициент: . 5.4. В цикле строить n секторов. Цвет сектора задавать случайно — каждая составляющая цвета изменяется в диапазоне от 1 до 245 (исключаем черный цвет и цвета близкие к белому). 5.5. Секторы определяются кругом радиуса R, вписанным в квадрат с координатами диагонали (x1; y1) — (x2; y2). Значения x1 = 50, y1 = 50, x2 = x1 + 2R, y2 = y1 + 2R, R = 200. 5.6. Расчет ключевых точек для построения сектора (см. рисунок). 5.7. Для построения сектора координаты точек (x3; y3) и (x4; y4) нужно преобразовать в экранные: увеличить горизонтальные на , а у вертикальных поменять знак и увеличить на . 5.8. Вывести надписи вверху компонента Image. Для вывода строк, считанных из файла, их нужно преобразовать так, чтобы можно было вывести на канву. Для этого можно воспользоваться функцией c_str(). Местоположение надписи рассчитывается так же и как для гистограммы.
|
Пример 15.3. Форма на этапе конструирования:
Текстовый файл с данными:
Подключение библиотек:
Обработчик события OnClick для компонента Button1.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//чтение данных из файла
ifstream fin("date.txt");
int n;
fin >> n;
vector <int> d(n);
vector <string> s(n);
for(int i = 0; i < n; i++)
fin >> s[i] >> d[i];
//поииск максимального
int n_max = 0;
for (int i = 0; i < n; i++)
if (d[i] > d[n_max])
n_max = i;
//коэффициент масштабирования
int h = Image1 -> Height - 40;
double k = 1. * h / d[n_max];
//ширина столбца
int w = Image1 -> Width/(2 * n + 1);
int x = w;
for (int i = 0; i < n; i++) {
//цвет
int cr = rand()% 245 + 1;
int cg = rand()% 245 + 1;
int cb = rand()% 245 + 1;
TColor c = TColor (RGB(cr, cg, cb));
Image1 -> Canvas -> Brush -> Color = c;
Image1 -> Canvas -> Rectangle
(x, h + 40, x + w, h - (int)(k * d[i]) + 30);
//надпись
Image1 -> Canvas -> Brush -> Color = clWhite;
Image1 -> Canvas -> Font -> Color = c;
Image1 -> Canvas -> TextOut
(x + 3, 3, s[i].c_str());
//переход к следующему столбцу
x += 2 * w;
}
}
|
Работающее приложение:
Пример 15.4. Форма на этапе конструирования:
Расчет ключевых точек для построения сектора:
Величина угла u2 соответствует текущему значению данных из массива и равна . Величина угла u1 — суммарное значение углов для уже построенных секторов. Вначале u1 = 0.
Значения x3 и y3 — катеты прямоугольного треугольника с углом u1 и гипотенузой равной радиусу круга, поэтому x3 = R cos u1, y3 = R sin u1.
Аналогично определяем x4 и y4: y4 = R cos (u1 + u2), y4 = R sin (u1 + u2).
Обработчик события OnClick для компонента Button1.
void __fastcall TForm1::Button1Click (TObject *Sender)
{
//чтение данных из файла
ifstream fin("date.txt");
int n;
fin >> n;
vector <int> d(n);
vector <string> s(n);
for(int i = 0; i < n; i++)
fin >> s[i] >> d[i];
//поииск суммы
int sum = 0;
for (int i = 0; i < n; i++)
sum += d[i];
//коэффициент масштабирования
double pi = acos(-1.);
double k = 2 * pi / sum;
//определение круга
double u1 = 0;
int w = Image1 -> Width/(2 * n + 1);
int x = w ;
int R = 200;
int x1 = 50, y1 = 50;
int x2 = x1 + 2 * R, y2 = y1 + 2 * R;
//центр области построения
int c_X = Image1 -> Width / 2;
int c_Y = Image1 -> Height / 2;
for (int i = 0; i < n - 1; i++){
double u2 = k * d[i];
int x3 = int (R * cos(u1)) + c_X;
int y3 = c_Y - int (R * sin(u1));
int x4 = int (R * cos(u1 + u2)) + c_X;
int y4 = c_Y - int (R * sin(u1 + u2));
//цвет
int cr = rand()% 255 + 1;
int cg = rand()% 255 + 1;
int cb = rand()% 255 + 1;
TColor c = TColor (RGB(cr, cg, cb));
Image1 -> Canvas -> Brush -> Color = c;
//сектор
Image1 -> Canvas -> Pie
(x1, y1, x2, y2, x3, y3, x4, y4);
//переход к следующему сектору
u1 += u2;
//надпись
Image1 -> Canvas -> Brush -> Color = clWhite;
Image1 -> Canvas -> Font -> Color = c;
Image1 -> Canvas ->
TextOut(x + 3, 3, s[i].c_str());
//переход к следующей надписи
x += 2 * w;
|
Работающее приложение:
|