График - вывод массива на печать (BDS 2006, C++)
Иногда в заданиях требуется выводить какие-либо данные в виде графика. В этом посте рассмотрим графическую часть подобной задачи.Формирование массива сделаем так же, как и в предыдущем варианте (печать столбиковой диаграммы).
Все элементы на форме оставляем прежними (сетка строк sg, кнопки «Новый массив» - btnNew, «Закрыть» - btnClose, рисунок im). Я не буду повторяться, поскольку все точно так же. Изменим лишь одну функцию ShowArray():
void ShowArray()Сначала нарисуем рамку вокруг рисунка с помощью функции «Прямоугольник» Canvas->Rectangle(0,0,wIm, hIm). Размеры соответствуют размерам элемента формы im.
{
int wIm = frmMain->im->Width; //ширина рисунка
int hIm = frmMain->im->Height; //высота рисунка
int x, h, hCol, wCol, i;
//рисуем рамку
frmMain->im->Canvas->Brush->Color = (TColor)RGB(255,255,255);
frmMain->im->Canvas->Rectangle(0,0,wIm, hIm);
//Заголовок
frmMain->im->Canvas->Font->Name = "Tahoma";
frmMain->im->Canvas->Font->Size = 13;
//выводим посередине рисунка
x = (frmMain->im->Width - frmMain->Canvas->TextWidth(title))/2;
frmMain->im->Canvas->Brush->Style = bsClear;
frmMain->im->Canvas->TextOutA(x,10,title);
frmMain->im->Canvas->Font->Style = TFontStyles()<<fsBold;
wCol = int((frmMain->im->Width-10)/arSize); //определяем расстояние между точками по горизонтали
x = 10; //позиция по горизонтали
int min, max; //максимальный и минимальный эелемент массива
min = 0; //принимаем за минимальный - первый элемент
max = 0; //принимаем за максимальный - первый элемент
for(i = 1; i<arSize; i++)
{
if (data[i] < data[min]) {
min = i; //если следующий меньше предыдущего, то он //минимальный
}
if (data[i]>data[max]) {
max = i; //так же с максимальным элементом
}
}
hCol = (frmMain->im->ClientHeight - 90)/data[max]; //коэффициент для расчета ординаты точки
for (i = 0; i < arSize; i++) {
h = hCol*data[i]; //высота, на которой выводим надпись
frmMain->im->Canvas->TextOutA(x-2,hIm-h-40, IntToStr(data[i]));
x+=wCol;
}
x = 15;
for (i = 0; i < arSize; i++) {
h = hCol*data[i]; //высота точки
//
if (i) {
frmMain->im->Canvas->LineTo(x,hIm-h); //проводим линию
}
frmMain->im->Canvas->Ellipse(x-2,hIm-h-2,x+2,hIm-h+2); //рисуем точку
frmMain->im->Canvas->MoveTo(x,hIm-h);
x+=wCol;
}
}
Затем устанавливаем название и размер шрифта и посередине рисунка выводим заголовок графика. Значения точек будем выводить жирным шрифтом, поэтому устанавливаем этот стиль шрифта с помощью свойства Style. Canvas->Font->Style = TFontStyles()<<fsBold.
Поскольку мы можем изменить размер рисунка или массива, каждый раз пересчитывать все параметры неудобно, поэтому рассчитаем расстояние между точками по горизонтали и коэффициент пересчета значения в координату по вертикали программно. Расстояние между точками зависит от количества элементов массива, а коэффициент рассчитаем от максимального значения. И, кстати, предполагаем, что у нас нет отрицательных значений в массиве, иначе расчет немного изменится. Но мы делаем самый простой вариант.
После подсчета значений коэффициентов в цикле выводим подпись каждой точки. Далее еще в одном цикле начинаем выводить сами точки в виде кружков (Ellipse), соединяя их линиями (LineTo), причем линию рисуем, если данная точка не первая. Для возврата в точку после рисования кружка необходимо использовать функцию MоveTo.
В общем, это все несложно пока. При реальном применении все гораздо сложнее.
