Содержание


Сервер &PlotSrv

Программа &PlotSrv - сервер научной графики на базе пакета GnuPlot.

Перейти к Содержанию


Назначение

Сервер &PLOTSRV обеспечивает построение всевозможных красиво оформленных графиков на основе использования широко распространенного в мире пакета GNUPLOT.

Этот сервер может строить графики прямо в памяти (без мелькания окошек на экране) и умеет генерировать файлы изображения, например GIF, что позволяет делать на его основе обработку в пакетном режиме.

Можно обозначить три сферы применения сервера:

  1. Генерация отчетов.
    Текстовая часть пишется в HTML, а изображения и графики генерируются сервером &PlotSrv в виде GIF файлов.

  2. Web - сервер.
    Генерация графиков для динамических Web страниц делается аналогично, текстовая часть HTML генерируется прямо в памяти, а изображения и графики генерируются сервером &PlotSrv в виде GIF файлов.

  3. Динамические мнемосхемы.
    Кликаем мышкой на сенсор. По этому клику &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:

PlotSend('@HomeDir=..\temp'+EOL               // Задание рабочего каталога GNUPLOT
         '@> set output "plot2.gif"'+EOL...)  // Задание GNUPLOT: в какой файл рисовать
   file=DaqFileRef('..\temp\plot2.gif','');   // Имя файла с точки зрения DaqPascal

То есть GNUPLOT работает с файлом plot2.gif, а CRW-DAQ с файлом ..2.gif, хотя это один и тот же файл.

@> set terminal gif size 300,200; set output "sinc.gif"
@> set title "Sinc function"
@> plot [0:10] sin(x)/x with lines
@# 0 1  - Кривая index 0
@# 1 2 
@#      - Разделитель
@#
@# 3 4  - Кривая index 1
@# 5 6 
   ...

Для доступа к данным в GNUPLOT используется конструкция index:

plot 'file.dat' index i using 1:2 ... где i-начинающийся с нуля номер кривой в списке
// Конвертировать GIF в BMP для обновления мнемосхемы
PlotSend('@! unix gif2bmp plot2.gif '+AdaptFileName('..\bitmaps\plot2.bmp')+EOL);

Следует помнить, что командный файл запускается в каталоге, заданном командой @HomeDir. Поэтому пути файлов указываются относительно этого каталога.

plot 'file.dat' index i using 1:2 ... где i-начинающийся с нуля номер кривой в списке
set 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).

Сообщения от сервера клиенту по окончании редактирования задаются самим клиентом через операторы @DoneMsg, @FailMsg поэтому клиентский код должен сам позаботиться о формате этого сообщения и о его корректной обработке.

Перейти к Содержанию


Примеры команд GNUPLOT

Команды 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

В настоящее время 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