mirror of
				https://github.com/dkogan/feedgnuplot.git
				synced 2025-10-31 16:28:10 +08:00 
			
		
		
		
	the --dataindex option has been changed to --dataid, with alphanumeric IDs. This necessiatated some
cleanup
This commit is contained in:
		
							
								
								
									
										157
									
								
								feedGnuplot.pl
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								feedGnuplot.pl
									
									
									
									
									
								
							| @@ -29,25 +29,26 @@ Usage: $0 [options] file1 file2 ... | ||||
|   --[no]domain         If enabled, the first element of each line is the | ||||
|                        domain variable.  If not, the point index is used | ||||
|  | ||||
|   --[no]dataindex      If enabled, each data point is preceded by the index | ||||
|                        of the data set that point corresponds to.  If not | ||||
|   --[no]dataid         If enabled, each data point is preceded by the ID | ||||
|                        of the data set that point corresponds to. This ID is | ||||
|                        interpreted as a string, NOT as just a number. If not | ||||
|                        enabled, the order of the point is used. | ||||
|  | ||||
| As an example, if line 3 of the input is "0 9 1 20" | ||||
|  '--nodomain --nodataindex' would parse the 4 numbers as points in 4 | ||||
|  '--nodomain --nodataid' would parse the 4 numbers as points in 4 | ||||
|    different curves at x=3 | ||||
|  | ||||
|  '--domain --nodataindex' would parse the 4 numbers as points in 3 different | ||||
|  '--domain --nodataid' would parse the 4 numbers as points in 3 different | ||||
|    curves at x=0. Here, 0 is the x-variable and 9,1,20 are the data values | ||||
|  | ||||
|  '--nodomain --dataindex' would parse the 4 numbers as points in 2 different | ||||
|    curves at x=3. Here 0 and 1 are the data indices and 9 and 20 are the | ||||
|  '--nodomain --dataid' would parse the 4 numbers as points in 2 different | ||||
|    curves at x=3. Here 0 and 1 are the data IDs and 9 and 20 are the | ||||
|    data values | ||||
|  | ||||
|  '--domain --dataindex' would parse the 4 numbers as a single point at | ||||
|    x=0. Here 9 is the data index and 1 is the data value. 20 is an extra | ||||
|  '--domain --dataid' would parse the 4 numbers as a single point at | ||||
|    x=0. Here 9 is the data ID and 1 is the data value. 20 is an extra | ||||
|    value, so it is ignored. If another value followed 20, we'd get another | ||||
|    point in curve number | ||||
|    point in curve ID 20 | ||||
|  | ||||
|  | ||||
|   --[no]stream         Do [not] display the data a point at a time, as it | ||||
| @@ -85,8 +86,8 @@ As an example, if line 3 of the input is "0 9 1 20" | ||||
|  | ||||
|   --y2max xxx          Set the range for the y2 axis. | ||||
|  | ||||
|   --y2    xxx          Plot the data with this index on the y2 axis. These are | ||||
|                        0-indexed | ||||
|   --y2    xxx          Plot the data specified by this curve ID on the y2 axis. | ||||
|                        Without --dataid, the ID is just an ordered 0-based index | ||||
|  | ||||
|   --curvestyle xxx     Additional style per curve. Give this option multiple | ||||
|                        times for multiple curves | ||||
| @@ -131,7 +132,7 @@ if(exists $ARGV[0] && !-r $ARGV[0]) | ||||
| # no monotonicity checks by default | ||||
| my %options = ( "stream"    => 0, | ||||
|                 "domain"    => 0, | ||||
|                 "dataindex" => 0, | ||||
|                 "dataid"    => 0, | ||||
|                 "points"    => 0, | ||||
|                 "lines"     => 0, | ||||
|                 "xlen"      => 0, | ||||
| @@ -140,7 +141,7 @@ my %options = ( "stream"    => 0, | ||||
| GetOptions(\%options, | ||||
|            "stream!", | ||||
|            "domain!", | ||||
|            "dataindex!", | ||||
|            "dataid!", | ||||
|            "lines!", | ||||
|            "points!", | ||||
|            "legend=s@", | ||||
| @@ -155,7 +156,7 @@ GetOptions(\%options, | ||||
|            "xmax=f", | ||||
|            "y2min=f", | ||||
|            "y2max=f", | ||||
|            "y2=i@", | ||||
|            "y2=s@", | ||||
|            "curvestyle=s@", | ||||
|            "extracmds=s@", | ||||
|            "size=s", | ||||
| @@ -184,6 +185,9 @@ if( defined $options{"help"} ) | ||||
| # references to lists of (x,y) tuples | ||||
| my @curves = (); | ||||
|  | ||||
| # list mapping curve names to their indices in the @curves list | ||||
| my %curveIndices = (); | ||||
|  | ||||
| # now start the data acquisition and plotting threads | ||||
| my $dataQueue; | ||||
| my $xwindow; | ||||
| @@ -317,26 +321,29 @@ sub mainThread { | ||||
| # For the specified values, set the legend entries to 'title "blah blah"' | ||||
|     if($options{"legend"}) | ||||
|     { | ||||
|       foreach (@{$options{"legend"}}) { newCurve($_, "") } | ||||
|     } | ||||
|  | ||||
| # For the values requested to be printed on the y2 axis, set that | ||||
|     foreach my $y2idx (@{$options{"y2"}}) | ||||
|     { | ||||
|       addCurveOption($y2idx, 'axes x1y2 linewidth 3'); | ||||
|       my $id = 0; | ||||
|       foreach (@{$options{"legend"}}) | ||||
|       { | ||||
|         setCurveLabel($id++, $_); | ||||
|       } | ||||
|     } | ||||
|  | ||||
| # add the extra curve options | ||||
|     if($options{"curvestyle"}) | ||||
|     { | ||||
|       my $idx = 0; | ||||
|       my $id = 0; | ||||
|       foreach (@{$options{"curvestyle"}}) | ||||
|       { | ||||
|         addCurveOption($idx, $_); | ||||
|         $idx++; | ||||
|         addCurveOption($id++, $_); | ||||
|       } | ||||
|     } | ||||
|  | ||||
| # For the values requested to be printed on the y2 axis, set that | ||||
|     foreach (@{$options{"y2"}}) | ||||
|     { | ||||
|       addCurveOption($_, 'axes x1y2 linewidth 3'); | ||||
|     } | ||||
|  | ||||
| # add the extra global options | ||||
|     if($options{"extracmds"}) | ||||
|     { | ||||
| @@ -359,12 +366,12 @@ sub mainThread { | ||||
|       if($_ ne "Plot now") | ||||
|       { | ||||
|         # parse the incoming data lines. The format is | ||||
|         # x idx0 dat0 idx1 dat1 .... | ||||
|         # where idxX is the index of the curve that datX corresponds to | ||||
|         # x id0 dat0 id1 dat1 .... | ||||
|         # where idX is the ID of the curve that datX corresponds to | ||||
|         # | ||||
|         # $options{domain} indicates whether the initial 'x' is given or not (if not, the line | ||||
|         # number is used) | ||||
|         # $options{dataindex} indicates whether idxX is given or not (if not, the point order in the | ||||
|         # $options{dataid} indicates whether idX is given or not (if not, the point order in the | ||||
|         # line is used) | ||||
|  | ||||
|         if($options{domain}) | ||||
| @@ -387,25 +394,25 @@ sub mainThread { | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         if($options{dataindex}) | ||||
|         if($options{dataid}) | ||||
|         { | ||||
|           while(/(\d+)\s+$numRE/go) | ||||
|           while(/(\w+)\s+$numRE/go) | ||||
|           { | ||||
|             my $idx   = $1; | ||||
|             my $point = $2; | ||||
|  | ||||
|             $haveNewData = 1; | ||||
|             pushPoint($idx, [$xlast, $point]); | ||||
|             pushPoint(getCurveIdx($1), | ||||
|                       [$xlast, $point]); | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           my $idx = 0; | ||||
|           my $id = 0; | ||||
|           foreach my $point (/$numRE/go) | ||||
|           { | ||||
|             $haveNewData = 1; | ||||
|             pushPoint($idx, [$xlast, $point]); | ||||
|             $idx++; | ||||
|             pushPoint(getCurveIdx($id++), | ||||
|                       [$xlast, $point]); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @@ -494,59 +501,59 @@ sub plotStoredData | ||||
|   } | ||||
| } | ||||
|  | ||||
| sub newCurve | ||||
| sub updateCurveOptions | ||||
| { | ||||
|   sub pushNewEmptyCurve | ||||
|   { | ||||
|     my $opts = "notitle "; | ||||
|     push @curves, [{"options" => " $opts"}]; | ||||
|   } | ||||
|   # generates the "options" string for a curve, based on its legend title and its other options | ||||
|   # These could be integrated into a single string, but that raises an issue in the no-title | ||||
|   # case. When no title is specified, gnuplot will still add a legend entry with an unhelpful '-' | ||||
|   # label. Thus I explicitly do "notitle" for that case | ||||
|  | ||||
|   # I optionally pass in the title of this plot and any additional options separately. The title | ||||
|   # COULD be a part of $opts, but this raises an issue in the no-title case. When no title is | ||||
|   # specified, gnuplot will still add a legend entry with an unhelpful '-' label. I can still grep | ||||
|   # $opts to see if a title is given, but that's a bit ugly in its own way... | ||||
|   my ($title, $opts, $idx) = @_; | ||||
|   my ($curveoptions) = @_; | ||||
|   my $titleoption = defined $curveoptions->{title} ? | ||||
|     "title \"$curveoptions->{title}\"" : "notitle"; | ||||
|  | ||||
|   $curveoptions->{options} = "$curveoptions->{extraoptions} $titleoption"; | ||||
| } | ||||
|  | ||||
| sub getCurveIdx | ||||
| { | ||||
|   # This function returns the curve index for a particular curve, creating a new curve if necessary | ||||
|  | ||||
|   if(scalar @curves >= $options{maxcurves}) | ||||
|   { | ||||
|     print STDERR "Tried to exceed the --maxcurves setting.\n"; | ||||
|     print STDERR "Invoke with a higher --maxcurves limit if you really want to do this.\n"; | ||||
|     return; | ||||
|     exit; | ||||
|   } | ||||
|  | ||||
|   # if this curve index doesn't exist, create curve up-to this index | ||||
|   if(defined $idx) | ||||
|   my ($id) = @_; | ||||
|  | ||||
|   if( !exists $curveIndices{$id} ) | ||||
|   { | ||||
|     while(!exists $curves[$idx]) | ||||
|     { | ||||
|       pushNewEmptyCurve(); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     # if we're not given an index, create a new one at the end, and fill it in | ||||
|     pushNewEmptyCurve(); | ||||
|     $idx = $#curves; | ||||
|   } | ||||
|     push @curves, [{extraoptions => ' '}]; # push a curve with no data and no options | ||||
|     $curveIndices{$id} =  $#curves; | ||||
|  | ||||
|   if(defined $title) { $opts = "title \"$title\" $opts" } | ||||
|   else               { $opts = "notitle $opts" } | ||||
|  | ||||
|   $curves[$idx] = [{"options" => " $opts"}]; | ||||
|     updateCurveOptions($curves[$#curves][0]); | ||||
|   } | ||||
|   return $curveIndices{$id}; | ||||
| } | ||||
|  | ||||
| sub addCurveOption | ||||
| { | ||||
|   my ($idx, $str) = @_; | ||||
|   if(exists $curves[$idx]) | ||||
|   { | ||||
|     $curves[$idx][0]{"options"} .= " $str"; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     newCurve('', $str, $idx); | ||||
|   } | ||||
|   my ($id, $str) = @_; | ||||
|  | ||||
|   my $idx = getCurveIdx($id); | ||||
|   $curves[$idx][0]{extraoptions} .= "$str "; | ||||
|   updateCurveOptions($curves[$idx][0]); | ||||
| } | ||||
|  | ||||
| sub setCurveLabel | ||||
| { | ||||
|   my ($id, $str) = @_; | ||||
|  | ||||
|   my $idx = getCurveIdx($id); | ||||
|   $curves[$idx][0]{title} = $str; | ||||
|   updateCurveOptions($curves[$idx][0]); | ||||
| } | ||||
|  | ||||
| # function to add a point to the plot. Assumes that the curve indexed by $idx already exists | ||||
| @@ -554,11 +561,7 @@ sub pushPoint | ||||
| { | ||||
|   my ($idx, $xy) = @_; | ||||
|  | ||||
|   if ( !exists $curves[$idx] ) | ||||
|   { | ||||
|     newCurve("", "", $idx); | ||||
|   } | ||||
|   elsif($options{monotonic}) | ||||
|   if($options{monotonic}) | ||||
|   { | ||||
|     my $curve = $curves[$idx]; | ||||
|     if( @$curve > 1 && $xy->[0] < $curve->[$#{$curve}][0] ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Dima Kogan
					Dima Kogan