Содержание
Программа &PlotSrv - сервер научной графики на базе пакета GnuPlot.
Сервер &PLOTSRV обеспечивает построение всевозможных красиво оформленных графиков на основе использования широко распространенного в мире пакета GNUPLOT.
Этот сервер может строить графики прямо в памяти (без мелькания окошек на экране) и умеет генерировать файлы изображения, например GIF, что позволяет делать на его основе обработку в пакетном режиме.
Можно обозначить три сферы применения сервера:
Генерация отчетов.
Текстовая часть пишется в HTML, а изображения и графики генерируются сервером &PlotSrv в виде GIF файлов.
Web - сервер.
Генерация графиков для динамических Web страниц делается аналогично, текстовая часть HTML генерируется прямо в памяти, а изображения и графики генерируются сервером &PlotSrv в виде GIF файлов.
Динамические мнемосхемы.
Кликаем мышкой на сенсор. По этому клику &PlotSrv создает график в виде GIF файла. По завершении &PlotSrv присылает клиенту уведомление. Клиент обновляет сенсор с помощью WinDraw(WindowName|Reload=SensorName). В результате это выглядит как мнемосхема, в которую "вмонтирован" GNUPLOT.
Пакет GNUPLOT довольно сложен, здесь не место его подробно обсуждать.
Вызывайте @run wgnuplot.hlp. Смотрите каталог gnuplot с многочисленными примерами. Читайте 1, 2, 2, 3, 4, 5.
Сервер &PlotSrv работает автономно и взаимодействует с клиентской программой только через сообщения.
Сервер &PlotSrv имеет ряд команд-сообщений, которые рекомендуется передавать одним сообщением в виде длинной строки текста, разделенной символами EOL на строки, через функцию PlotSend, имеющуюся в шаблонах редактирования.
В командах передаются
1. Параметры настройки сервера - как запускать GNUPLOT (в каком каталоге и т.д.), какие сообщения он сгенерирует после завершения работы GNUPLOT и т.д.
2. Задание (job) для GNUPLOT, которое определяет что и как надо рисовать.
3. Данные (dat) для отображения, могут задаваться таблицей в сообщениях, или ссылкой на кривые, или ссылкой на файл.
4. Команды (bat) которые выполняются после работы GNUPLOT. Например, это может быть преобразование GIF в BMP. Мнемосхемы "не понимают" формат GIF, поэтому картинки надо преобразовывать в BMP, например, утилитой gif2bmp.
Важно понять, что при вызове сервера клиент передает ему в блоке параметров ответное сообщение, которое будет передано клиенту при завершении работы GNUPLOT. Клиент же должен уметь обрабатывать это сообщение, присланное сервером. Например, клиент может при получении сообщения обновить окна или вызвать обозреватель HTML.
Таким образом, клиент посылает серверу задание на рисование графиков, в которое включено ответное сообщение, а после завершения рисования клиент получает это ответное сообщение, позволяющее обновить изображение окна.
Поскольку результатом работы GNUPLOT и &PlotSrv будет файл (GIF или BMP), очень важно правильно обращаться с файлами. Особенно это касается путей файлов - их надо внимательно отслеживать, так как пакет CRW-DAQ и GNUPLOT работают в разных каталогах и короткие (относительные) пути файлов в программах DaqPascal и скриптах GNUPLOT будут несколько отличаться, как показано ниже. Будьте внимательны.
При вызове &PlotSrv рекомендуется передавать все команды в одном длинном сообщении, разделяя команды символами EOL, а также рекомендуется использовать стандартную функцию PlotSend, которая имеется в шаблонах редактирования.
Пример рисования графика Plot2 из двух кривых:
// Если нажат сенсор...
if ClickButton=1 then begin
// Начать редактирование тега...
if ClickTag=tagPlot2 then
b:=PlotSend('@Clear'+EOL
+'@TimeOut 5000'+EOL
+'@HomeDir ..\Temp'+EOL
+'@DoneMsg &DemoPlot @Done '+AdaptFileName('..\Bitmaps\plot2.bmp')+EOL
+'@FailMsg &DemoPlot @Fail '+AdaptFileName('..\Bitmaps\plot2.bmp')+EOL
+'@# 0 0'+EOL // Кривая 1
+'@# 1 2'+EOL
+'@# 2 4'+EOL
+'@# 3 8'+EOL
+'@#'+EOL+'@#'+EOL // Разделитель кривых
+'@# 0 0'+EOL // Кривая 2
+'@# 1 1'+EOL
+'@# 2 3'+EOL
+'@> set encoding utf8'+EOL
+'@> set output "plot2.gif"'+EOL
+'@> set terminal gif small size 300,200 font "PT Mono,7"'+EOL
+'@> set title "График по таблице (linespoints, boxes)" font "PT Mono,8"'+EOL
+'@> set xlabel "Время, секунд" font "PT Sans,10"'+EOL
+'@> set ylabel "Значение" font "PT Serif,10"'+EOL
+'@> set grid; set key left top; set xrange [0:10]'+EOL
+'@> plot "plot2.dat" index 0 using 1:2 with linespoints pt 13 ti "Кривая 1", \'+EOL
+'@> "plot2.dat" index 1 using 1:2 with boxes ti "Кривая 2"'+EOL
+'@! unix gif2bmp plot2.gif '+AdaptExeFileName('..\Bitmaps\plot2.bmp')+EOL
+'@run plot2.job plot2.dat plot2.bat'+EOL)>0;
end;Разберем вызов подробнее.
\ или /), регистр, расширение исполняемых файлов.Соответственно клиент должен обрабатывать на сообщение @Done ..\Bitmaps\plot2.bmp для принятия мер в случае успешного рисования (например, перерисовки окна мнемосхемы для отображения графика). Клиент должен обрабатывать сообщение @Fail ..\Bitmaps\plot2.bmp для принятия мер в случае ошибки рисования (например, перерисовки графика или выдачи сообщения).
Смотри также demo_gnuplot.
При вызове &PlotSrv клиент посылает серверу текст двух ответных сообщений (@DoneMsg, @FailMsg), которое он желает получить от сервера по окончании рисования, как успешного, так и неуспешного.
Например, при указании @DoneMsg=&DemoPlot @Done ..\Bitmaps\Plot2.bmp сервер после успешного рисования пошлет устройству &DemoPlot сообщение @Done ..\Bitmaps\Plot2.bmp, которое содержит имя файла с графиком, чтобы по нему можно было обновить тег или окно. Не забывайте, что имя файла возможно потребуется адаптировать функцией AdaptFileName. Клиент должен уметь обрабатывать это сообщение.
Пример обработки сообщения:
{
Analyse data coming from standard input.
}
procedure StdIn_Process(Data:string);
var cmd,arg:String; b:Boolean; tag:Integer;
begin
{
"@cmd=arg" or "@cmd args" commands:
}
cmd:='';
arg:='';
if GotCommand(Data,cmd,arg) then begin
{}
if IsSameText(cmd,'@Done') then begin
// Reload sensor bitmap from file specified by arg
// Assume that file name = tag name = sensor name
tag:=FindTag(ExtractFileName(arg));
if TypeTag(tag)=1 then begin
b:=iSetTag(tag,Ord(FileExists(DaqFileRef(AdaptFileName(arg),''))));
if iGetTag(tag)<>0 then b:=WinDraw('DemoPlot|Reload='+NameTag(tag));
Success(cmd+'='+Str(iGetTag(tag)));
end else Problem(cmd+'=?');
Data:='';
end;
{}
if Length(Data)>0 then begin
Trouble(' Unrecognized command "'+Data+'".');
Data:='';
end;
end;
cmd:='';
arg:='';
end;В примере полагается, что файл ..\Bitmaps\Plot2.bmp соответствует сенсору Plot2, связанному с тегом Plot2, поэтому по имени файла находится тег и затем обновляется сенсор.
Чтобы использовать &PlotSrv, клиент должен включить в конфигурацию:
[ConfigFileList]
ConfigFile = ~~\resource\daqsite\default\plotsrv.cfgПри необходимости можно изменить параметры по умолчанию, включив в основной конфигурационный файл что-то вроде
[&PlotSrv]
DebugFlags = 15
OpenConsole = 2
StdInFifo = 128 ; FIFO size for StdIn
StdOutFifo = 128 ; FIFO size for StdOut
TimeOut = 10000 ; Time limit for GNUPLOT execution
HomeDir = ..\temp ; Default work directory for GNUPLOT
JobFile = gnuplot.job ; Default file for (temporary) GNUPLOT job
DatFile = gnuplot.dat ; Default file for (temporary) data table(s)
BatFile = gnuplot.bat ; Default file for (temporary) batch filter
[]Все перечисленные параметры необязательны, они или берутся по умолчанию, или включаются в задание на рисование.
Чтобы избежать пересечений имен, не рекомендуется использовать теги, начинающиеся на &PlotSrv, так как этот префикс можно считать зарезервированным для сервера &PlotSrv.
Сервер &PlotSrv работает автономно и взаимодействует с клиентской программой только через сообщения и файлы, являющиеся результатом его работы.
Вот список сообщений от клиента серверу &PlotSrv:
@Clear
Эта команда приводит &PlotSrv в начальное состояние и очищает все буферы ввода. С этой команды должно начинаться каждое новое задание на рисование.
@Cd=dir То же самое, что @HomeDir=dir.
@HomeDir=dir
Устанавливает рабочий каталог dir файлов GNUPLOT. Путь dir указывается по обычным правилам конфигурационных файлов: относительные пути прописываются относительно главного конфигурационного файла. Имейте в виду, что GNUPLOT запускается в каталоге HomeDir, а поэтому в задании для GNUPLOT короткие файловые ссылки указываются относительно каталога HomeDir, а не относительно главного конфигурационного файла. Например, если указан каталог **HomeDir=..*, то упоминаемый в задании на рисование файл plot2.gif будет расположен, с точки зрения DaqPascal, в каталоге **..*.
PlotSend('@HomeDir=..\temp'+EOL // Задание рабочего каталога GNUPLOT
'@> set output "plot2.gif"'+EOL...) // Задание GNUPLOT: в какой файл рисовать
file=DaqFileRef('..\temp\plot2.gif',''); // Имя файла с точки зрения DaqPascalТо есть GNUPLOT работает с файлом plot2.gif, а CRW-DAQ с файлом ..2.gif, хотя это один и тот же файл.
@TimeOut=t
Задает серверу &PlotSrv предельное время (в миллисекундах) на выполнение задания. Если сервер не успел выполнить задание за это время, задание убивается и клиенту посылается сообщение, заданное в команде @FailMsg=....
@> job
Добавляет строку задания job в буфер заданий &PlotSrv. При наличии хотя бы одной строки заданий в буфере, накопленные команды записываются в файл задания (job), а затем имя этого файла передается на исполнение в команду @run для запуска GNUPLOT . Если задание постоянно (зафиксировано в файле), то в буфер заданий ничего писать не надо, иначе файл будут перезаписан.
Надо отметить, что сама по себе команда записи в буфер ничего не делает, она просто сохраняет текст задания для дальнейшего исполнения командой @run.
Пример:
@> set terminal gif size 300,200; set output "sinc.gif"
@> set title "Sinc function"
@> plot [0:10] sin(x)/x with lines@# dat@# 0 1 - Кривая index 0
@# 1 2
@# - Разделитель
@#
@# 3 4 - Кривая index 1
@# 5 6
...Для доступа к данным в GNUPLOT используется конструкция index:
plot 'file.dat' index i using 1:2 ... где i-начинающийся с нуля номер кривой в списке@! bat// Конвертировать GIF в BMP для обновления мнемосхемы
PlotSend('@! unix gif2bmp plot2.gif '+AdaptFileName('..\bitmaps\plot2.bmp')+EOL);Следует помнить, что командный файл запускается в каталоге, заданном командой @HomeDir. Поэтому пути файлов указываются относительно этого каталога.
@DoneMsg=msg
Задает ответное сообщение, которое сервер &PlotSrv посылает клиенту для уведомления об успешном завершении рисования. Например, при указании @DoneMsg=&DemoPlot @Done ..\Bitmaps\Plot2.bmp сервер после успешного рисования пошлет устройству &DemoPlot сообщение @Done ..\Bitmaps\Plot2.bmp, которое содержит имя файла с графиком, чтобы по нему можно было обновить тег или окно. Клиент должен уметь обрабатывать это сообщение.
@FailMsg=msg
Задает ответное сообщение, которое сервер &PlotSrv посылает клиенту для уведомления об ошибке рисования. Например, при указании @FailMsg=&DemoPlot @Fail ..\Bitmaps\Plot2.bmp сервер после успешного рисования пошлет устройству &DemoPlot сообщение @Fail ..\Bitmaps\Plot2.bmp, которое содержит имя файла с графиком, чтобы по нему можно было что-то предпринять. Клиент должен уметь обрабатывать это сообщение.
@CurveList=crv
Добавляет кривую в список кривых для рисования в &PlotSrv. При наличии хотя бы одной кривой в списке накопленные в кривых данные записываются в файл данных (dat) перед выполнением команды @run, а имя этого файла используется в тексте задания GNUPLOT. Если данные помещены в (постоянном) файле, то в список кривых ничего писать не надо, иначе файл будут перезаписан. Если данные передаются как талица в сообщении @# dat, то в список кривых ничего писать тоже не надо.
Для доступа к данным в GNUPLOT используется конструкция
plot 'file.dat' index i using 1:2 ... где i-начинающийся с нуля номер кривой в списке@XTime=tb,tu или @XTime=Defaultset xdata time; set timefmt "%Y.%m.%d-%H:%M:%S"
## Это формат для чтения таблицы типа
2009.01.20-15:30:00 3.14
2009.01.20-15:31:00 2.17
## Формат времени соответствует шаблонной функции GetDateTime(msecnow).@YTime=tb,tu или @YTime=Default
Аналогично @XTime, только все относится к оси Y.
@Run job dat bat
Эта команда всегда стоит последней в сообщениии от клиента к серверу. Она запускает задание &PlotSrv на исполнение, используя файл задания job, файл данных dat и файл команд bat. Обычно это временные файлы, которые создаются при исполнении команды и куда записывается содержимое буферов ввода заданий, данных и команд фильтра. Если задание задавалось командами @> .., то перезаписывается файл job. Если данные задавалось командами @# .. или @СurveList .., то перезаписывается файл dat. Если команды задавались с помощью @! .., то перезаписывается файл bat. Если же файлы имеют постоянный характер, в соответствующие буферы ничего записывать не надо, иначе файл будет перезаписан.
Все три файла задаются в URL-кодировке. Для обычных файлов это ничего не значит, а для файлов с пробелами или спецсимволами может пригодиться. Все три файла необязательно указывать, при их опускании подставляется файл по умолчанию. Однако рекомендуется файлы указывать явно - ведь на них все равно может потребоваться ссылка в тексте задания GNUPLOT.
После подготовки файлов &PlotSrv запускает GNUPLOT в домашнем каталоге, заданном командой @HomeDir. Задание содержит директивы GNUPLOT в файле job, а в результате ожидается генерация файлов изображений (рекомендуется GIF). При необходимости файлы GIF конвертируются в файлы BMP с помощью командного файла - фильтра bat, содержащего команду типа gif2bmp source.gif target.bmp. Командный файл вызывается при успешном завершении GNUPLOT.
В конце задания сервер отсылает клиенту сообщение, заданное оператором @DoneMsg или @FailMsg, в зависимости от результата выполнения задания. Клиент должен обрабатывать эти сообщеия.
Сообщения от сервера клиенту по окончании редактирования задаются самим клиентом через операторы @DoneMsg, @FailMsg поэтому клиентский код должен сам позаботиться о формате этого сообщения и о его корректной обработке.
Команды GNUPLOT передаются с помощью PlotSend('@> '+cmd+EOL).
Наиболее полезные из них:
set encoding utf8 ## Универсальная кодировка
set terminal gif size 640,480 font "PT Sans,10" ## Рисовать в GIF файл, заданного размера, заданным шрифтом
set xrange[-1:1]; set yrange[-3:3] ## Задать пределы рисования
set title "Заголовок" font "PT Mono,12" ## Задать заголовок с шрифтом
set xlabel "Надпись по X"; set ylabel "Надпись по Y" ## Задать надписи по осям, можно с шрифтом
set grid; set key left top ## Задать рисование сетки и положение легенды
plot "f.dat" index 0 using 1:2 with lp lc 1 lw 2 pt 3 ## рисовать файл данныхСмотрите также каталог gnuplot/demo с многочисленными примерами.
В настоящее время GNUPLOT поддерживает универсальную кодировку utf8, поэтому для корректной передачи текста задания надо её указать. Кроме того, в тексте задания надо указать фонт:
set encoding utf8 ## Универсальная кодировка
set terminal gif size 640,480 font "PT Sans,10" ## Рисовать в GIF файл, заданного размера, заданным шрифтомВ качастве фонтов можно указывать любые доступные в системе шрифты.
Однако рекомендуется использовать шрифты ParaType:
- Моноширинный PT Mono
- Без засечек PT Sans
- С засечками PT Serif
Эти шрифты свободно распространяются и доступны на всех системах.
Желаем успешного использования &PlotSrv.
CRW-DAQ Copyright (c) 2001-2024 Alexey Kuryakin daqgroup@mail.ru