LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C++ cgi using gnuplot to draw graph on the web (https://www.linuxquestions.org/questions/programming-9/c-cgi-using-gnuplot-to-draw-graph-on-the-web-4175668300/)

hpdp 01-23-2020 02:11 PM

C++ cgi using gnuplot to draw graph on the web
 
My c++ program uses the gnuplot interface from Gnuplot-iostream.h

It takes an input string and produces runtime data to draw a graph. The program works on linux command line.

I need to use cgi to run it from web, then user can enter a string and see the graph. when I call this cgi from web, the error says "sh: gnuplot: command not found"

I tried to put in test.cgi
Code:

#!/bin/sh
PATH=/usr/local/gnuplot/5.0.1/bin/gnuplot
export PATH
exec /web/mycode.cgi "$@"
exit 1

but it didn't work. thanks!
Code:

Gnuplot gp;
std::vector<std::pair<double, double> > xy_pts_A;

xy_pts_A.push_back(std::make_pair(49, 22));
xy_pts_A.push_back(std::make_pair(50, 32));
xy_pts_A.push_back(std::make_pair(51, 52));
xy_pts_A.push_back(std::make_pair(52, 87));
xy_pts_A.push_back(std::make_pair(53, 29));

gp << "set term svg\n";  //comment out for running from command line,
gp << "set xrange [49:99]\nset yrange [0:100]\n"; 
gp << "plot '-' with lines title 'cubic'\n";
gp.send1d(xy_pts_A);


NevemTeve 01-23-2020 02:58 PM

Instead:
Code:

PATH="/usr/local/gnuplot/5.0.1/bin:$PATH"
export PATH


michaelk 01-23-2020 05:10 PM

What you posted is c++ source code but it must be compiled before it can be executed. There is more to creating a bash cgi script then what is posted. Here is some old documentation but should still be relevant.

http://www.yolinux.com/TUTORIALS/BashShellCgi.html

You need to enable cgi-bin scripts in the web server configuration files. Typically web input is handled by forms and then processed by a script which does not have to be bash, i.e. php, python, perl, ruby and others. I would guess you would use gnuplot to create a png file of your plot/graphs.

scasey 01-23-2020 05:53 PM

1 Attachment(s)
Quote:

Originally Posted by michaelk (Post 6082213)
You need to enable cgi-bin scripts in the web server configuration files. Typically web input is handled by forms and then processed by a script which does not have to be bash, i.e. php, python, perl, ruby and others. I would guess you would use gnuplot to create a png file of your plot/graphs.

That’s how I do it...use perl to create the files to pass to gnuplot, and build the web page to display the resulting graphs

hpdp 01-23-2020 10:45 PM

I'm limited to use C++ cgi. What I posted above is just an example code, "mycode.C", I compiled it and has no problem in calling a cgi by submitting a form from web.
I can run mycode.cgi from command line, it draws the graph. It just doens't work from the web.

if I put
Code:

gp << "set output \"test.svg\"\n";
in the souce code, it will write out a svg file, I can call the svg file to display from web. But we are not allowed to write data from web for security reasons. I need to find a way to display the graph directly.

From the error message, my guess is web server can't find gnuplot, so I tried to set PATH in a shell script first. But it didn't work.
I tried NevemTeve's suggestion, it didn't work either.
Thanks!

scasey 01-23-2020 11:07 PM

Does “doesn’t work” mean your still getting the not found error? please be specific about what’s happening...”doesn’t work” gives us no information to help you with.

Your cgi script may be creating the graph, but you also need to code/create a web page to display it. Do you have code n your script to create a web page?

Why are you limited to c++...is this homework?

NevemTeve 01-24-2020 02:15 AM

If you can redirect your svg-format output into a file, then perhaps you can redirect it into 'stdout' too.

Whatever a Cgi program writes to stdout, that will be sent to the client.

See this: https://stackoverflow.com/questions/...out-in-gnuplot

hpdp 01-24-2020 11:22 AM

The actual C++ code is written by other people. It takes an input string and produces runtime data based on the input to draw a graph. It seems I didn't describe the problem clearly. My example c++ mycode.C is
Code:

int main() {
Gnuplot gp;
std::vector<std::pair<double, double> > xy_pts_A;

xy_pts_A.push_back(std::make_pair(49, 22));
xy_pts_A.push_back(std::make_pair(50, 32));
xy_pts_A.push_back(std::make_pair(51, 52));
xy_pts_A.push_back(std::make_pair(52, 87));
xy_pts_A.push_back(std::make_pair(53, 29));

gp << "set xrange [49:99]\nset yrange [0:100]\n"; 
gp << "plot '-' with lines title 'cubic'\n";
gp.send1d(xy_pts_A);
}

I compiled it to mycode.cgi, I can run this cgi from command line, it shows the graph. But when I called this cgi by submitting a form from a web-page. It didn't load the graph, it gave a general server error message. The web log error was:
"AH01215: sh: gnuplot: command not found
AH01215: pclose returned error
End of script output before headers: mycode.cgi"

test.html is
Code:

<html>
<head>
<title>upright.html</title>
</head>
<body>
<form name="myform" action="mycode.cgi">
<input type="text" name="term">
<br><input type="submit" value="Search" >
<br><input type="button" value="Reset">
</form>
</body>
</html>


scasey 01-24-2020 12:23 PM

Quote:

Originally Posted by hpdp (Post 6082490)
I compiled it to mycode.cgi, I can run this cgi from command line, it shows the graph. But when I called this cgi by submitting a form from a web-page. It didn't load the graph, it gave a general server error message. The web log error was:
"AH01215: sh: gnuplot: command not found
AH01215: pclose returned error
End of script output before headers: mycode.cgi"

A "command not found" error suggests that the path to gnuplot is not known to the script. The PATH statement you've provided appears to include the program. It should not to that. Set the PATH as suggested in #2

You will need to supply at least a http header line when outputting the graph. While it is true that "Whatever a Cgi program writes to stdout, that will be sent to the client," the web server is choking because the first thing sent needs to be a http header:
Code:

Content-type: text/html
...the following blank line is signifcant.

NevemTeve 01-24-2020 01:41 PM

> I can run this cgi from command line, it shows the graph.

What does it that actually mean? The svg-content is listed on the terminal? A GUI-window is opened with the image?

hpdp 01-27-2020 06:04 PM

> I can run this cgi from command line, it shows the graph.
> What does it that actually mean? The svg-content is listed on the terminal? A GUI-window is opened with the image?

It means that A gui-window is opened with the image.

If I put the following line in mycode.C and recompite it to mycode.cgi:
Code:

cout<<"Content-TYPE: image/svg+xml\n\n";
Gnuplot gp;
....  //  the rest is the same

When this cgi was called from url, the webpage displayed:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
It's blank after this line.
When running this cgi from commandlie, a gui-window was opened with the graph.

Thanks for any help.

hpdp 01-27-2020 06:36 PM

When I added this line in mycode, and recompiled it
Code:

gp << "set term svg\n";
running from command line, it didn't open a gui-window with the graph, but printout the output of svg content.
I piped the output to a svg file
./mycode.cgi > mycode.svg

then I called this svg file from url http://.../mycode.svg
the webpage displayed the graph.

scasey 01-27-2020 07:36 PM

Yes. That’s how we do it too.
1. The script creates a “file” (we actually create an html file/page) containing the graph.
2. The browser calls the file/web page.

hpdp 01-27-2020 08:38 PM

>> Yes. That’s how we do it too.
>> The script creates a “file” (we actually create an html file/page) containing the graph.
>> The browser calls the file/web page.

But I'm trying to call mycode.cgi from browser to display the graph directly, instead of calling a graph file made by mycode.cgi.
Because the graph is dynamic based on user's input text, and multiple users can use the website at the same time.
Is this doable?

scasey 01-27-2020 09:18 PM

Quote:

Originally Posted by hpdp (Post 6083642)
>> Yes. That’s how we do it too.
>> The script creates a “file” (we actually create an html file/page) containing the graph.
>> The browser calls the file/web page.

But I'm trying to call mycode.cgi from browser to display the graph directly, instead of calling a graph file made by mycode.cgi.
Because the graph is dynamic based on user's input text, and multiple users can use the website at the same time.
Is this doable?

Yes.. see #9 you have to write the header..


All times are GMT -5. The time now is 11:03 PM.