——————# -----------------------------------------------------------------------------
=encoding utf8
=head1 NAME
Quiq::Gd::Component::ScatterGraph - Farbpunkte in einer Fläche
=head1 BASE CLASS
L<Quiq::Gd::Component::Graph>
=head1 DESCRIPTION
Die Klasse erweitert die Basisklasse Quiq::Gd::Component::Graph um
eine Z-Komponente. Die Werte dieser Komponente werden in Farbwerte
ĂĽbersetzt und in den Positionen der X,Y-Komponenten abgetragen.
=head1 ATTRIBUTES
Weitere Attribute sind in der Basisklassen-Dokumentation beschrieben.
=over 4
=item z => \@z (Default: [])
Array der Z-Werte (Weltkoordinate).
=item zMin => $float (Default: Minimum der Z-Werte)
Anfang des Z-Wertebereichs (Weltkoodinate).
=item zMax => $float (Default: Maximum der Z-Werte)
Ende des Z-Wertebereichs (Weltkoodinate).
=item zLogarithmic => $bool (Default: 0)
Bilde den Z-Wertebereich logarithmisch auf die Farbwerte ab.
=item lowColor => $color (Default: undef)
Farbe fĂĽr Z-Werte, die zMin unterschreiten.
=item highColor => $color (Default: undef)
Farbe fĂĽr Z-Werte, die zMax ĂĽberschreiten.
=back
=head1 EXAMPLE
Code:
use Quiq::Gd::Image;
use Quiq::Gd::Component::ScatterGraph;
# Konfiguration
my $width = 200;
my $height = 200;
my $numColors = 128;
my $pointSize = 10;
# Zufallsdaten erzeugen
my (@x,@y,@z);
for (1 .. 300) {
push @x,int rand 100;
push @y,int rand 100;
push @z,int rand 128;
}
# Grafik-Objekt instantiieren
my $g = Quiq::Gd::Component::ScatterGraph->new(
width=>$width,
height=>$height,
pointSize=>$pointSize,
pointStyle=>'circle',
adaptPlotRegion=>1,
x=>\@x,
y=>\@y,
z=>\@z,
lineThickness=>0,
);
# Bild-Objekt instantiieren
my $img = Quiq::Gd::Image->new($width,$height);
$img->background('ffffff');
$img->border('a0a0a0');
# Grafik auf Bild zeichnen
$g->render($img,0,0,
colors=>[$img->rainbowColors($numColors)],
lowColor=>$img->color('003366'),
highColor=>$img->color('ff00ff'),
);
Grafik:
[Nur im Browser sichtbar]
=cut
# -----------------------------------------------------------------------------
package
Quiq::Gd::Component::ScatterGraph;
use
v5.10;
use
strict;
use
warnings;
our
$VERSION
=
'1.225'
;
use
Quiq::Option;
use
Quiq::Array;
use
POSIX ();
# -----------------------------------------------------------------------------
=head1 METHODS
=head2 Konstruktor
=head3 new() - Konstruktor
=head4 Synopsis
$g = $class->new(@keyVal);
=head4 Description
Instantiiere ein Grafik-Objekt mit den Eigenschaften @keyVal
(s. Abschnitt L<ATTRIBUTES|"ATTRIBUTES">) und liefere eine Referenz auf das Objekt
zurĂĽck.
=cut
# -----------------------------------------------------------------------------
sub
new {
my
$class
=
shift
;
# @_: @keyVal
my
$opt
= Quiq::Option->extract(
-properties
=>1,
-mode
=>
'sloppy'
,\
@_
,
z
=> [],
zMin
=>
undef
,
zMax
=>
undef
,
zLogarithmic
=> 0,
lowColor
=>
undef
,
highColor
=>
undef
,
);
my
$self
=
$class
->SUPER::new(
@_
);
$self
->add(
%$opt
);
# Z-Minimum und Z-Maximum berechnen, falls nicht angegeben.
# Dies mĂĽssen wir im Konstruktor machen, damit die Objektmethoden
# zMin() und zMax() korrekte Wert liefern.
my
$zMin
=
$self
->{
'zMin'
};
my
$zMax
=
$self
->{
'zMax'
};
if
(!
defined
$zMin
) {
$zMin
= Quiq::Array->min(
$self
->{
'z'
}) // 0;
}
if
(!
defined
$zMax
) {
$zMax
= Quiq::Array->max(
$self
->{
'z'
}) // 0;
}
if
(
$zMin
==
$zMax
) {
$zMin
-= 1;
$zMax
+= 1;
}
$self
->{
'zMin'
} =
$zMin
;
$self
->{
'zMax'
} =
$zMax
;
return
$self
;
}
# -----------------------------------------------------------------------------
=head2 Zeichnen
=head3 render() - Zeichne Grafik
=head4 Synopsis
$g->render($img);
$g->render($img,$x,$y,@keyVal);
$class->render($img,$x,$y,@keyVal);
=head4 Description
Zeichne die Grafik in Bild $img an Position ($x,$y).
Die Methode liefert keinen Wert zurĂĽck.
=cut
# -----------------------------------------------------------------------------
sub
render {
my
$this
=
shift
;
my
$img
=
shift
;
my
$x
=
shift
|| 0;
my
$y
=
shift
|| 0;
# @_: @keyVal
my
$self
=
$this
->self(
@_
);
# Attribute
my
$zA
=
$self
->{
'z'
};
my
$zMin
=
$self
->{
'zMin'
};
my
$zMax
=
$self
->{
'zMax'
};
my
$zLogarithmic
=
$self
->{
'zLogarithmic'
};
my
$colorA
=
$self
->{
'colors'
};
my
$lowColor
=
$self
->{
'lowColor'
};
my
$highColor
=
$self
->{
'highColor'
};
# Daten fĂĽr das Rendern durch die Basisklasse aufbereiten
my
$min
=
$zLogarithmic
? POSIX::log10(
$zMin
):
$zMin
;
my
$max
=
$zLogarithmic
? POSIX::log10(
$zMax
):
$zMax
;
my
@c
;
for
(
@$zA
) {
my
$z
=
$zLogarithmic
? POSIX::log10(
$_
):
$_
;
my
$c
;
if
(
$z
<
$min
) {
$c
=
$lowColor
;
}
elsif
(
$z
>
$max
) {
$c
=
$highColor
;
}
else
{
my
$i
= Quiq::Math->valueToPixel(
scalar
(
@$colorA
),
$min
,
$max
,
$z
);
$c
=
$colorA
->[
$i
];
}
push
@c
,
$c
;
}
# Zeichnen (ĂĽbernimmt die Basisklasse)
$self
->SUPER::render(
$img
,
$x
,
$y
,
colors
=> \
@c
,
);
return
;
}
# -----------------------------------------------------------------------------
=head2 Objektmethoden
=head3 zMin() - Minimum des Z-Wertebereichs
=head4 Synopsis
$zMin = $g->zMin;
=head4 Description
Liefere das Minimum des Z-Wertebereichs, das entweder beim
Konstruktoraufruf gesetzt oder aus den Daten ermittelt wurde.
=cut
# -----------------------------------------------------------------------------
sub
zMin {
return
shift
->{
'zMin'
};
}
# -----------------------------------------------------------------------------
=head3 zMax() - Maximum des Z-Wertebereichs
=head4 Synopsis
$zMax = $g->zMax;
=head4 Description
Liefere das Maximum des Z-Wertebereichs, das entweder beim
Konstruktoraufruf gesetzt oder aus den Daten ermittelt wurde.
=cut
# -----------------------------------------------------------------------------
sub
zMax {
return
shift
->{
'zMax'
};
}
# -----------------------------------------------------------------------------
=head1 VERSION
1.225
=head1 AUTHOR
Frank Seitz, L<http://fseitz.de/>
=head1 COPYRIGHT
Copyright (C) 2025 Frank Seitz
=head1 LICENSE
This code is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
# -----------------------------------------------------------------------------
1;
# eof