Hi James,
On 24/06/2013 20:23, James Lynes wrote:
Should be easy to
pull the generated file into a PaintDC if you don't want to launch an
outboard file viewer. I may or may not get to that.
I added a simple viewer to your code by:
1. changing your Graph method a little
2. adding display classes DisplayDialog and DisplayPanel
I though it would be useful to demo getting the raw data from your GD
object and displaying it in a Wx::Panel without needing to save to a
file. It also removes the need for an external viewer and is cross platform.
Hope it helps
Mark
#! /home/pete/CitrusPerl/perl/bin/perl
# ImpedanceGraph.pl
# Impedance calculator for Ls & Cs with graphic display
#
# Calculates the impedance for a range of frequencies and graphs.
# Graph and save_chart borrowed(stolen) from GD::Graph sample51.pl
#
# James M. Lynes, Jr.
# Last Modified: June 24, 2013
#
package main;
use strict;
use warnings;
my $app = App->new();
$app->MainLoop;
package App;
use strict;
use warnings;
use base 'Wx::App';
sub OnInit {
Wx::InitAllImageHandlers();
my $frame = Frame->new();
$frame->Show(1);
}
package DisplayPanel;
use strict;
use warnings;
use Wx qw(:everything);
use base qw(Wx::Panel);
use Wx::Event qw( EVT_PAINT );
sub new {
my ($class, $parent, $bitmap) = @_;
my $self = $class->SUPER::new($parent, -1,
wxDefaultPosition,
[ $bitmap->GetWidth, $bitmap->GetHeight ],
wxBORDER_NONE);
$self->{bitmap} = $bitmap;
EVT_PAINT($self, \&OnEvtPaint);
return $self;
}
sub OnEvtPaint {
my ($self, $event) = @_;
my $dc = Wx::PaintDC->new($self);
$dc->DrawBitmap($self->{bitmap}, 0,0,0);
}
package DisplayDialog;
use strict;
use warnings;
use Wx qw(:everything);
use base qw(Wx::Dialog);
sub new {
my($class, $parent, $image) = @_;
my $self = $class->SUPER::new($parent, -1, 'GD::Graph Image Display');
my $bitmap = Wx::Bitmap->new($image);
my $canvas = DisplayPanel->new($self, $bitmap);
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
$sizer->Add($canvas,1,wxEXPAND|wxALL,0);
$self->SetSizerAndFit($sizer);
return $self;
}
package Frame;
use strict;
use warnings;
use Wx qw(:everything);
use base qw(Wx::Frame);
use Wx::Event qw(EVT_BUTTON EVT_CHOICE);
use GD::Graph::lines;
use Data::Dumper;
sub new {
my($self) = @_;
$self = $self->SUPER::new(undef, -1, "L or C Impedance Graph",
wxDefaultPosition, wxDefaultSize);
my @Inductors = ("nH", "uH", "mH");
my @Capacitors = ("pF", "nF", "uF");
$self->{lmultiplyer} = 1E-09;
$self->{cmultiplyer} = 1E-12;
$self->{freqs} = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
$self->{st1} = Wx::StaticText->new($self, -1, "Inductor Value", Wx::Point->new(25,50),
wxDefaultSize, wxALIGN_LEFT);
$self->{st2} = Wx::StaticText->new($self, -1, "Capacitor Value", Wx::Point->new(25,100),
wxDefaultSize, wxALIGN_LEFT);
$self->{st5} = Wx::StaticText->new($self, -1, "Enter an L or C. Impedance Sweep will be Graphed",
Wx::Point->new(25,15), wxDefaultSize, wxALIGN_LEFT);
$self->{tc1} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150,50), Wx::Size->new(100,20));
$self->{tc2} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150,100), Wx::Size->new(100,20));
$self->{tc1}->SetValue(0);
$self->{tc2}->SetValue(0);
$self->{lc} = Wx::Choice->new($self, 1, Wx::Point->new(250, 50), wxDefaultSize, \@Inductors);
$self->{cc} = Wx::Choice->new($self, 2, Wx::Point->new(250, 100), wxDefaultSize, \@Capacitors);
$self->{bt1} = Wx::Button->new($self, 4, "Graph Cs", Wx::Point->new(25,200), wxDefaultSize);
$self->{bt1} = Wx::Button->new($self, 5, "Graph Ls", Wx::Point->new(150,200), wxDefaultSize);
$self->{bt1} = Wx::Button->new($self, 6, "Clear All", Wx::Point->new(25,150), wxDefaultSize);
$self->{bt2} = Wx::Button->new($self, wxID_CLOSE, "Exit", Wx::Point->new(25,300), wxDefaultSize);
EVT_BUTTON($self, 4, \&CalcC);
EVT_BUTTON($self, 5, \&CalcL);
EVT_BUTTON($self, 6, \&ClearAll);
EVT_BUTTON($self, wxID_CLOSE, \&Close);
EVT_CHOICE($self, 1, \&ChoiceL);
EVT_CHOICE($self, 2, \&ChoiceC);
return $self;
}
sub CalcC {
my($self, $event) = @_;
my @values;
my $C = $self->{tc2}->GetValue * $self->{cmultiplyer};
if($C == 0) {return};
foreach my $F (@{$self->{freqs}}) {
my $I = 1/(6.28 * $C * $F);
push(@values, $I);
}
$self->Graph(\@values);
}
sub CalcL {
my($self, $event) = @_;
my @values;
my $L = $self->{tc1}->GetValue * $self->{lmultiplyer};
if($L == 0) {return};
foreach my $F (@{$self->{freqs}}) {
my $I = 6.28 * $L * $F;
push(@values, $I);
}
$self->Graph(\@values);
}
sub ChoiceL {
my($self, $event) = @_;
if($self->{lc}->GetSelection == 0) {$self->{lmultiplyer} = 1E-09};
if($self->{lc}->GetSelection == 1) {$self->{lmultiplyer} = 1E-06};
if($self->{lc}->GetSelection == 2) {$self->{lmultiplyer} = 1E-03};
}
sub ChoiceC {
my($self, $event) = @_;
if($self->{cc}->GetSelection == 0) {$self->{cmultiplyer} = 1E-12};
if($self->{cc}->GetSelection == 1) {$self->{cmultiplyer} = 1E-09};
if($self->{cc}->GetSelection == 2) {$self->{cmultiplyer} = 1E-06};
}
sub ClearAll {
my($self, $event) = @_;
$self->{tc1}->SetValue(0);
$self->{tc2}->SetValue(0);
}
sub Close {
my($self, $event) = @_;
$self->Destroy;
}
sub Graph {
my($self, $values) = @_;
my @data = (
[ qw( 1 10 100 1K 10K 100K 1M 10M 100M 1G) ],
[(@{$values})],
);
my $my_graph = new GD::Graph::lines(600,400);
$my_graph->set(
x_label => 'Frequency(Hz)',
y_label => 'Impedance(Ohms)',
title => 'Impedance vs Frequency',
y_max_value => 50000,
y_min_value => 0,
y_tick_number => 20,
y_label_skip => 2,
box_axis => 0,
line_width => 3,
transparent => 0,
x_label_position => 1/2,
);
my $gd = $my_graph->plot(\@data);
#save_chart($my_graph, 'impedance');
#system('eog /home/pete/Projects/perlprojects/RFdesign/impedance.gif');
# Get the raw PNG data
my $png = $gd->png;
# Get a file handle and load it as a wxImage
open my $fh, '<', \$png;
my $img = Wx::Image->new($fh, &Wx::wxBITMAP_TYPE_PNG);
close $fh;
my $dialog = DisplayDialog->new($self, $img);
$dialog->Centre;
$dialog->ShowModal();
$dialog->Destroy;
}
sub save_chart
{
my $chart = shift or die "Need a chart!";
my $name = shift or die "Need a name!";
local(*OUT);
my $ext = $chart->export_format;
open(OUT, ">$name.$ext") or
die "Cannot open $name.$ext for write: $!";
binmode OUT;
print OUT $chart->gd->$ext();
close OUT;
}
1;