- •Основы работа с графикой на с#
- •Глава 1. Использование графики в Windows приложениях
- •Параграф 2. Создание линейных графиков
- •2.1. В качестве постановки задачи
- •2.2. Постановка задачи
- •2.3. Исходные данные
- •2.4. Проект решения
- •2.5. Конструкторы класса
- •2.6. Создаем объект для рисования
- •2.7. Рисуем оси
- •2.8. Рисуем сетку
- •2.8. Рисуем линию графика
- •2.10. Надписи на графике
- •Параграф 3. Создание гистограмм
- •Параграф 5. Базовый класс для рисования графиков
2.10. Надписи на графике
Надписи можно наносить по оси Х, по оси Y и над точками линий графика. Причем иногда бывает целесообразно выполнять соседние надписи со сдвигом по оси Y. Кроме того - надписи выполняются не пером, а кистями и требуют задания шрифта. Таким образом, перед выполнением надписей надо установить в классе соответственно шрифт и кисть (Brush).
Для передачи шрифта и кисти создадим в классе свойства:
public Brush brush
{
set { objBrush = value; }
}
public Font font
{
set { objFont = value; }
}
В функции рисования графика запишем код:
Font objFont = new Font("Arial", 12, FontStyle.Bold | FontStyle.Italic);
clPaint.font = objFont;
clPaint.brush = Brushes.Blue;
Для выполнения различных надписей создадим в классе несколько функций. Подробно давать пояснения нет необходимости. Здесь, как и при рисовании линий, необходимо постоянно рассчитывать дельны расстояний по осям и точки начала надписей.
#region Текст по оси X - Цифры отсчетов
//Параметр: false - соседние значения без сдвига по оси Y
// true - соседние значения со здвигом по оси Y
public void vDrawTextAxXNumber(bool f)
{
//Пикселей для надписей по оси х
float fdeltax = viX - viDeltaaxisL - viDeltaaxisR;
//Пикселей на один отсчет
fdeltax = fdeltax / (float)(viMaxRg - 1);
float x = viDeltaaxisL;
float y = viY - viDeltaaxisH + objPenLine.Width;
for (int i = 1; i < viMaxRg + 1; i++)
{
if (!f || i % 2 == 0)
{
graph.DrawString(Convert.ToString(i), objFont, objBrush, x + (i - 1) * fdeltax, y);
}
else
{
graph.DrawString(Convert.ToString(i),
objFont, objBrush, x + (i - 1) * fdeltax, y + objFont.Size);
}
}
}
#endregion
#region Текст по оси X - Параметр массива
//Параметр: false - соседние значения без сдвига по оси Y
// true - соседние значения со здвигом по оси Y
public void vDrawTextAxXValues(bool f)
{
string s = string.Empty;
//Пикселей для надписей по оси х
float fdeltax = viX - viDeltaaxisL - viDeltaaxisR;
//Пикселей на один отсчет
fdeltax = fdeltax / (float)(viMaxRg - 1);
float x = viDeltaaxisL;
float y = viY - viDeltaaxisH;// +objPenLine.Width;
for (int i = 0; i < viMaxRg; i++)
{
if (!f || i % 2 == 0)
{
graph.DrawString(rgsValues[i, 1], objFont, objBrush, x + i * fdeltax, y);
}
else
{
graph.DrawString(rgsValues[i, 1], objFont, objBrush, x + i * fdeltax, y + objFont.Size);
}
}
}
#endregion
#region Текст по оси Y - Значения по отсчетам сетки оси Y
public void vDrawTextAxYValues()
{
string s = string.Empty;
float f = 0;
float fMax = float.MinValue;
for (int i = 0; i < viMaxRg; i++)
{
s = rgsValues[i, 0];
if (fMax < float.Parse(s)) fMax = float.Parse(s);
}
f = fMax / (float)(viMaxRg - 1);
//Пикселей для надписей по оси х
float fdeltay = viY - 2 * viDeltaaxisH;
//Пикселей на один отсчет
fdeltay = fdeltay / (float)(viMaxRg - 1);
float y = viY - viDeltaaxisH - objFont.Size;
for (int i = 0; i < viMaxRg; i++)
{
graph.DrawString(((float)(i * f)).ToString("0.00"),
objFont, objBrush, viDeltaaxisL - (objFont.Size) * 5 - 5, y - i * fdeltay);
}
}
#endregion
#region Надписи - Значения над точкой
//1 параметр = false - без отображения процентов, true - с отображением
//2 параметр = false - без сдвига, true - со здвигом по оси Y
public void vDrawTextAxYValuesPoint(bool a, bool b)
{
string s = string.Empty;
float fMax = float.MinValue;
float fSum = 0;
for (int i = 0; i < viMaxRg; i++)
{
s = rgsValues[i, 0];
fSum += float.Parse(s);
if (fMax < float.Parse(s)) fMax = float.Parse(s);
}
//Пикселей для надписей по оси х
float fdeltax = viX - viDeltaaxisL - viDeltaaxisR;
//Пикселей на один отсчет по х
fdeltax = fdeltax / (float)(viMaxRg - 1);
float x = viDeltaaxisL;
float fdeltay = viY - 2 * viDeltaaxisH;
float y = viY - viDeltaaxisH - objFont.Size;
//Пикселей на одну единицу
fdeltay = fdeltay / fMax;
float fdelta = 0;
for (int i = 0; i < viMaxRg; i++)
{
if (a)
{
if (i % 2 == 0) fdelta = objFont.Size;
else fdelta = 2 * objFont.Size;
}
else
{
fdelta = objFont.Size;
}
if (b)
{
graph.DrawString(rgsValues[i, 0], objFont, objBrush, x + i * fdeltax,
y - (float.Parse(rgsValues[i, 0]) * fdeltay) - fdelta);
}
else
{
float fp = float.Parse(rgsValues[i, 0]);
fp = (fp * 100) / fSum;
graph.DrawString(rgsValues[i, 0] + "-" + fp.ToString("0.0") + "%",
objFont, objBrush, x + i * fdeltax,
y - (float.Parse(rgsValues[i, 0]) * fdeltay) - fdelta);
}
}
}
#endregion
Мы создали полностью код для отображения линейного графика. Все функции для управления построением и изменения внешнего вида представлены в void vCreateLinGr():
private void vCreateLinGr()
{
//Создаем массив значений для вывода на графике
vCreateRg();
//Создаем класс и передаем ему размер холсты
PaintCl clPaint = new PaintCl(pictureBox1.Width, pictureBox1.Height);
//Фон холста
clPaint.vSetBackground(Color.White);
//Параметры вызоыва: отступы слева, справа, сверху(снизу),Цвет осей, толщина пера
clPaint.vDravAxis(50, 50, 30, Color.Red, 2,true);
clPaint.vSetPenWidthLine(1);
clPaint.vSetPenColorLine(Color.Silver);
clPaint.MaxRg = 20;
clPaint.vDravGrid();
clPaint.vSetPenWidthLine(2);
clPaint.vSetPenColorLine(Color.Green);
clPaint.RgValue = rgsValues;
clPaint.vDrawGraphLines();
Font objFont = new Font("Arial", 7, FontStyle.Bold | FontStyle.Italic);
clPaint.font = objFont;
clPaint.brush = Brushes.Blue;
//Здесь необходимо поэксперементировать с
//использованием различных надписей и изменением параметров
clPaint.vDrawTextAxXNumber(false);
//clPaint.vDrawTextAxXValues(true);
clPaint.vDrawTextAxYValues();
clPaint.vDrawTextAxYValuesPoint(true,false);
//Принимаем нарисованное в pictureBox
pictureBox1.Image = clPaint.Bmp;
}
Результат выполнения кода показан на Рис.10.:
Рис.10. Линейный график
