Читать книгу Программирование для Android и работа с датчиками в среде Delphi 11 - Виталий Иванович Донцов - Страница 20

11. КОМПОНЕНТЫ ДЛЯ 2D И 3D ГРАФИКИ
11.2. Группа компонентов Shape

Оглавление

Все фигуры можно взять готовыми из группы Shapes, что значительно упрощает работу с ними через готовые свойства и настройки. В Delphi Android, однако, компонент TPath, удобный для линейного графика, конфликтует с TPath классом, ответственным за работу с файлами, и System.IOUtils в Use.

Прямоугольник Rectagle подойдет для отображения столбчатых графиков. Компонент можно сделать цветным и окрасить градиентом, например, в красный или зеленый цвет, показывая границы нормы.



Рис. 29. Построение графиков из элементов Rectangle по данным таблицы.


Для линейного графика можно использовать компонент Path: TPath, рисующий полилинию, а также компонент PlotGrid, представляющий собой просто сетку. Чтобы координата Y шла вверх (а отсчет Y ведется от левого верхнего угла вниз), и находилась в пределах PlotGrid, можно координату Y задавать как:

y1:= Form1.Height – (Form1.Height – PlotGrid1.Height) – y;

var

p: TPointF;

i: Integer;

x,y,kX, kY, x1,x2,y1,y2:Double;

s: String;

begin

//Коэффициенты Х и Y

kX:= StrToFloat (Edit1.Text);

kY:= StrToFloat (Edit2.Text);

//Оси задаются

x:= 1; // Ось Y

y:= 1;

p.X:= x;

p.Y:= y;

Path1.Data.MoveTo (p);

x:= 1;

y:= 360;

p.X:= x;

p.Y:= y;

Path1.Data.LineTo (p);

x:= 1; // Ось Х

y:= 360;

p.X:= x;

p.Y:= y;

Path1.Data.MoveTo (p);

x:= 360;

y:= 360;

p.X:= x;

p.Y:= y;

Path1.Data.LineTo (p);

//Проверка наличия данных

if Memo1.Lines [0] = «» then

begin

ShowMessage («Введете данные X;Y!»);

Exit;

end;

//График

s:= Memo1.Lines [0];

s:= Copy (s,1,Pos (» -», s) -1); // Выделение Х из строки

x:= StrToFloat (s);

s:= Memo1.Lines [0]; // Выделение Y из строки

s:= Copy (s, Pos (» -», s) +1,100);

y:= StrToFloat (s);

x1:= kX*x; // Учет коэффициентов для данных

y1:= Form1.Height – (Form1.Height – PlotGrid1.Height) – kY*y;

p.X:= x1;

p.Y:= y1;

Path1.Data.MoveTo (p); //Начало графика

//График

for i:= 1 to Memo1.Lines.Count-1 do

begin

s:= Memo1.Lines [i];

s:= Copy (s,1,Pos (» -», s) -1);

x:= StrToFloat (s);

s:= Memo1.Lines [i];

s:= Copy (s, Pos (» -», s) +1,100);

y:= StrToFloat (s);

x1:= kX*x;

y1:= Form1.Height – (Form1.Height – PlotGrid1.Height) – kY*y;

p.X:= x1;

p.Y:= y1;

Path1.Data.LineTo (p); // Очередная линия графика

end;

Надо заметить, что компонент рисует график сразу, причем самостоятельно масштабирует его во всю свою длину и ширину, так что можно просто наложить по размеру компонент на PlotGrid. Повторные графики рисуются с сохранением предыдущих, причем большие графики изменяют масштаб предыдущих, а меньшие рисуются в пределах существующего.


Рис. 30. Построение графиков с помощью компонента Path1 на фоне компонента PlotGrid.


Ранее заданные оси координат (синия линии по Х оси) автоматически увеличены под новый график.

«Стереть» линии можно просто с помощью Path1.Data.Clear.

Чтобы график не выходил за заданные масштабы и компонент не навязывал свой масштаб, данные для графика должны быть в пределах координатных заданных осей X и Y. Для того, чтобы задать масштаб компоненту нужно нарисовать вначале линии координат. Вводить данные можно из Memo.

Для масштабирования графика можно задать вводимый масштаб для данных через компоненты Edit:

kX:= StrToFloat (Edit1.Text);

kY:= StrToFloat (Edit2.Text);


Компонент Path можно использовать и для вывода данных в реальном времени, когда работа с данными периодически дополняет график, для этого достаточно добавлять данные в Memo и использовать его свойство onChage для перерисовки графика (очищаем график с помощью Path1.Data.Clear и рисуем заново с новыми данными).

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

var

p: TPointF;

i, rnd: Integer;

n: Single;

kY, x1,x2,y,y1:Double;

s: String;

begin

if Edit1.Text = «1» then //Случайные данные для проверки!

begin //На ширину Path = 119 данных по 3 точки

//Начальную точку устанавливаем к началу координат.

if NumberBox6.Value = 0 then

begin

NumberBox6.Value:= 1;

p.X:= 1;

p.Y:= Path1.Height -1;

Path1.Data.MoveTo (p);

end;

rnd:= Random (100) *5+10; //Случайные данные

NumberBox2.Value:= rnd;//Истинное значение выводится

kY:= StrToFloat (Edit2.Text); //Коэффициент Y

NumberBox5.Value:= NumberBox5.Value+1;//Счет данных

NumberBox6.Value:= NumberBox6.Value+1;//Счет для цикла

s:= FloatToStr(NumberBox4.Value*NumberBox5.Value) + '; ' + FloatToStr(NumberBox2.Value); //В Memo истинные данные

Memo1.Lines.Add (s);

//Рисуем график не выходя за пределы Path

x1:= NumberBox6.Value*3;// 3 Точки на 1 значение Х

y:= rnd*kY;

if y <= Path1.Height – 5 then //Коррекция Y

begin

y1:= Path1.Height – kY*y;

p.X:= x1;

p.Y:= y1;

if NumberBox6.Value> = 119 then //За пределы Х

begin

Path1.Data.Clear;

NumberBox6.Value:= 0;//Новый цикл! С начало

end

else

Path1.Data.LineTo (p) //Рисуем график – линию

end

else // Y За пределы графика

begin

p.X:= x1;

p.Y:= 2;

Path1.Data.MoveTo (p);//Прерывание графика

end; endend;


Рис. 31. Регистратор сигналов на базе компонента Path.


На рисунке представлен вид такого регистратора (в режиме теста – регистрация случайных данных – Random (100) +1) *2).

Другие фигуры также могут быть использованы для графика: эллипс (как вариант – круг) может быть использована для точечного графика (как и просто точка) с применением Rect координат:

R.Top:= Path1.Height – Y; // Координата Y, отсчет сверху

R.Bottom:= R.Top+2;

R. Left:= X; // Координата Х (в пределах Path. Width)

R. Right:=R. Left+2;

Path1.Data.AddEllipse (R); //Добавление очередного объекта

Аналогично, TPie может быть использован для кругового графика (заполненная цветом – как сектор).

Для надписей также есть своя фигура TText.

К сожалению Path: TPath графика конфликтует с Path: TPath пути для файлов! Поэтому одновременно рисовать и сохранять данные не получится; придется использовать рисование: Path: TPathData.

Программирование для Android и работа с датчиками в среде Delphi 11

Подняться наверх