Avatar billede haolan Nybegynder
08. maj 2007 - 13:13 Der er 6 kommentarer og
1 løsning

Grafer med GDlib i et koordinatsystem

Hej eksperter..

Jeg skal have lavet nogle grafer med lidt kurver på.
Der skal i graferne være to kurver der følger en X og en Y akse.

Eksempel 1:

Der skal vises en graf over antal kørte km månedsvis på et år.

Dvs x-aksen er måned (janaur, februar osv..)
og Y-aksen er total antal km for den pågældene måned.

Eksempel 2:
Der skal vises en graf over antal kørte km om dagen på en måned.
Der skal også tages højde for at der ikke nødvendigvis køres på alle dage

Dvs x-aksen er dag (1. Januar, 2. Januar osv..)
og Y-aksen er total antal km for den pågældene måned.

Alle data bliver trukket ud fra en MySQL database.

Hvordan laver man den slags grafer?

Skal lige nævnes at jeg har ingen erfaringer med GDlib
Avatar billede intenz Novice
08. maj 2007 - 18:53 #1
Prøv at kig på JpGraph:
http://www.aditus.nu/jpgraph/
Avatar billede haolan Nybegynder
08. maj 2007 - 19:13 #2
har desværre ikke rettigheder til at installere på serverne, da det er et webhotel..

jpgraph er et library der skal installeres ikke?
Avatar billede intenz Novice
08. maj 2007 - 19:15 #3
nej, det er bare filer der skal includes.

gd-lib skal dog være installeret på serveren.
Avatar billede haolan Nybegynder
08. maj 2007 - 19:17 #4
gd-lib er installeret ved jeg.. bruger det i forvejen til noget captcha..

Er der ikke et sted man kan hente det som zip fil? Jeg bruger windows når jeg udvikler, så kan ikke pakke tar.gz filen ud..
Avatar billede intenz Novice
08. maj 2007 - 19:33 #5
Download winzip, www.winzip.com, den kan pakke den ud.
Eller winrar til noget andet. De fleste "rigtige" pakke programmer kan pakke det ud.
Avatar billede olympus Nybegynder
09. maj 2007 - 02:26 #6
Hej haolan!

Jeg havde et script liggende, som jeg havde skrevet til en kammerat, med en lignende opgave. Jeg er sikker på, du kommer længst med at skrive dit eget. Jeg blev ikke helt færdig med at kommentere det, men det kører fint. Hvis du nærlæser dette script, som udskriver søjler efter et array, og det script som ligger her:

http://www.eksperten.dk/artikler/1066

så skulle du være godt rustet til din opgave. Happy Coding :-)



<?php
/******************************
Af J.Bek  Islands Brygge  Dec. 2006

Som lovet en intro til GD-lib. At skabe et billede, er ikke så svært. Det er mere det, at få
smækket noget fornuftigt på det, og lige fange, hvordan GD-lib arbejder!

******************************/

header( 'Content-Type: image/png; charset=UTF-8\r\n' );

/*
Allerførst skal jeg bruge nogle data, så jeg har lavet et par arrays.
Scriptet kører med det første datasæt ($data), men omdøb det, og omdød et af de andre til $data,
for at skifte mellem datasæt (og det samme nede i $titel)
*/
$data = array(
"1992" => 137930,
"1993" => 178032,
"1994" => 148935,
"1995" => 192885,
"1996" => 111304,
"1997" => 125304,
"1998" => 156304,
"1999" => 142057,
"2000" => 133057,
"2001" => 167057,
"2002" => 139057,
"2003" => 164733,
"2004" => 178498,
"2005" => 78317,
"2006" => 203467,
);

$data1 = array(
"Jan" => 3.7,
"Feb" => 4.2,
"Mar" => 8.4,
"Apr" => 10.2,
"Maj" => 14.6,
"Jun" => 18.7,
"Jul" => 19.8,
"Aug" => 22.8,
"Sep" => 17.1,
"Okt" => 11.3,
"Nov" => 5.6,
"Dec" => 1.4,
);

$data2 = array(
"Første Kvartal" => 1469458,
"Andet Kvartal" => 2648792,
"Tredie Kvartal" => 2832597,
"Fjerde Kvartal" => 2578207,
);

//Jeg hiver lige nogle størelser ud af data
$max_vaerdi = max($data);
$antal_vaerdier = count($data);



//Jeg laver Grundbilledet
$bredde = 800;
$hoejde = 400;
$mit_billede = imagecreate($bredde,$hoejde);

/*Så jeg har en række data og et tomt billede.
Så skal jeg bruge nogle farver, til at tegne billedet med.
Farveskemaer kan findes mange forskellige steder på nettet
og i f.eks. MS indbyggede Paint. Kald funktionen med parametrene:
(Navnet på billedet som skal bruge farven, rød, grøn, blå)
*/

$hvid = imagecolorallocate($mit_billede, 255, 255, 255);
$sort = imagecolorallocate($mit_billede, 0, 0, 0);
$moerk_blaa = imagecolorallocate($mit_billede, 0, 0, 180);
$lys_blaa = imagecolorallocate($mit_billede, 190, 190, 255);
$lyseblaa = imagecolorallocate($mit_billede, 235, 235, 255);
$roed = imagecolorallocate($mit_billede, 255, 0, 0);
$groen = imagecolorallocate($mit_billede, 0, 255, 0);
$gul = imagecolorallocate($mit_billede, 255, 255, 0);
$graa = imagecolorallocate($mit_billede, 190, 190, 190);

//Jeg fylder en baggrunds-farve i hele billedet
imagefill($mit_billede, 0, 0, $lys_blaa);

//Og jeg sætter en horisontal magen, som jeg kun bruger i venstre side, - der hvor grænselinie-etiketterne skal udskrives
$horisontal_margen = 60;
//Og sætter en vertikal margen, som jeg bruger i top og bund, - til overskrift og søjle-etiketter
$vertikal_margen = 20;
/*
Jeg vil godt ha' lidt "luft" mellem søjlerne, og efter den sidste søjle.
Jeg beregner det nu, for at få de ydre rammer i orden
*/
$luft = 20;
//Jeg regner lige på, hvor bredde søjlerne kan være
$soejle_br = floor(($bredde - $luft - $horisontal_margen) / $antal_vaerdier);
//Så sætter jeg min "kanvas-bredde"
$kanvas_bredde = $antal_vaerdier * $soejle_br + $luft;
/******************
Resultatet af den beregning, kan godt sende rammen ud over kanten på billedet,
fordi jeg deler og ganger op igen, så det vil jeg lige undersøge
******************/
if($kanvas_bredde + $horisontal_margen > $mit_billede){
    $soejle_br = $soejle_br - 1;
    $kanvas_bredde = $antal_vaerdier * $soejle_br + $luft;
}
//Og min "kanvas-højde"
$kanvas_hoejde = $hoejde - 2 * $vertikal_margen;

//Og fylder farve i kanvas
imagefilledrectangle($mit_billede, $horisontal_margen, $vertikal_margen, $horisontal_margen + $kanvas_bredde, $vertikal_margen + $kanvas_hoejde, $lyseblaa );

//Og jeg sætter en ramme rundt om kanvas. Rammen overskriver kanten af det forige rektangel
imagerectangle($mit_billede, $horisontal_margen, $vertikal_margen, $horisontal_margen + $kanvas_bredde, $vertikal_margen + $kanvas_hoejde, $sort);

/*
Jeg må
hellere gi' tallene en overskrift, på noget det kunne være:
*/

$titel = "Antal besøgende i Gribskov";
$titel1 = "Gennemsnits temperaturer";
$titel2 = "Regnskabstal";
$titelfont_str = 5;
$text_bredde = imagefontwidth($titelfont_str) * strlen($titel);


//Så centrerer jeg titlen over mit kanvas
$x_position = round($horisontal_margen + ($kanvas_bredde - $text_bredde)/2);
/*Jeg gennemtvinger en positiv x_position. Hvis resultat af
beregningen opover (hvis titel-teksten er større end mit kanvas) skulle blive negativt,
så bliver tekstens startposition ikke mindre end 1
*/
$x_position = max(1, $x_position);
//Og sætter jeg afstanden til toppen
$y_position = 2;
/*og kalder billedtekst-funktionen med alle de parametre,
den skal bruge til min titel.
*/
imagestring($mit_billede, $titelfont_str, $x_position, $y_position, $titel, $roed);

/*


$font_ttf = "c:/programmer/easyphp1-8/www/arial.ttf";
$tekst_vinkel = 0;

ImageTTFText ($mit_billede, $titelfont_str, $tekst_vinkel, $x_position, $y_position, $roed, $font_ttf, $titel);
*/


/*
Jeg skal også ha' lavet mine grænselinie-etiketter, med data fra mit array,
og jeg skal ha' lavet nogle grænselinier, så man har noget at sammenligne
søjlehøjderne med.
Men data fra et tilfældigt array, delt med x antal_grænselinier, kan
gi' nogle helt ubrugelige grænselinie-værdier, så jeg "renser" lige det værste væk,
ved at beholde 1 eller 2 cifre (ciffer_rest), længst til venstre, og rutchje en gang med
kommaet, frem og tilbage, mens jeg "lofter" resultatet i en øvre_grænse
*/
$ciffer_rest = 2;
$ciffer_antal = strlen(round($max_vaerdi)) - $ciffer_rest;
$oevre_graense = ceil($max_vaerdi / pow(10, $ciffer_antal)) * pow(10, $ciffer_antal);
/*
Jeg lægger 1 til antal_grænselinier
*/
$etiketfont_str = 2;
$antal_graenselinier = 10;
$hoejdedata_mellem_granser = $oevre_graense / $antal_graenselinier;
$pixelhoejde_mellem_graenser = $kanvas_hoejde / ($antal_graenselinier + 1);

/*
Nu begynder jeg at tegne grænselinier op, og udskrive etiketter i venstre margen.
Jeg sætter en tæller ind, og laver en løkke
*/
for ($taeller = 0; $taeller <= ($antal_graenselinier + 1); $taeller ++){


    $y_data = ceil($taeller * $hoejdedata_mellem_granser);
/*
Jeg skal bruge en y-højde (y_position) til at udskrive, både grænselinien og grænselinie-teksten på.
*/
    $y_position = $vertikal_margen + $kanvas_hoejde - round($taeller * $pixelhoejde_mellem_graenser);
//Jeg skal også bruge en tekst-bredde og tekst-højde
    $text_bredde = imagefontwidth($etiketfont_str) * strlen($y_data);
    $text_hoejde = imagefontheight($etiketfont_str);
//Og jeg skal ha' centreret teksten i venstre horisontal_margen
    $x_position = round(($horisontal_margen - $text_bredde) / 2);
//Og lige som med titlen, gennemtvinge en positiv x_position
    $x_position = max(1, $x_position);
/*
Og så skriver teksten ud.
Jeg centrerer teksten ud for y_positonen
*/
    imagestring($mit_billede, $etiketfont_str, $x_position, $y_position - (round($text_hoejde / 2)), $y_data, $sort);
    if(!($taeller == 0) && !($taeller > $antal_graenselinier)){

//Og skriver grænselininen ud

    imageline($mit_billede, $horisontal_margen + 1, $y_position,  $horisontal_margen + $kanvas_bredde - 1, $y_position, $graa);
       
        /*Jeg lægger 1 til startpositionen og trækker 1 fra slutpositionen,
        for ikke at overskrive den pixel, rammen består af.
        Jeg kunne ha' ventet med at skrive rammen ud til sidst, og derved
        overskrevet de par pixels, som hver linie tegner for langt.
        */
       
    }
}

/*
Jeg vil ha' søjlerne i forskellige farver. Det kan jeg lave på mange måder,
men her vælger jeg en switch.
Jeg sætte en farve_tæller ind, til at holde styr på farve-skiftet
*/
$farve_taeller = 0;
/*
*/
$soejle_hoejde_enhed = ($kanvas_hoejde - 2) / $y_data;

for ($taeller = 0; list($foerste_element, $andet_element) = each($data); $taeller ++){

$farve_taeller ++;

    switch($farve_taeller) {
        case ("1"):
        $soejle_farve = $moerk_blaa;
        break;
        case ("2"):
        $soejle_farve = $gul;
        break;
        case ("3"):
        $soejle_farve = $groen;
        break;
        case ("4"):
        $soejle_farve = $roed;
        $farve_taeller = 0;//Jeg nulstiller lige farve_tælleren, når den er 4
        break;
        default:
        $soejle_farve = $moerk_blaa;
        }
/*
Så kommer min nul-linie værdi, - y_max. Minus 1, hvis søjlen ikke skal overskrive rammen i bunden,
men jeg tegner også en ramme rundt om søjlen
*/
    $y_max = $vertikal_margen + $kanvas_hoejde;//
   
    $y_min = $y_max - round($andet_element * $soejle_hoejde_enhed);
    $x_max = $horisontal_margen + ($taeller + 1) * $soejle_br;
    $x_min = $horisontal_margen + ($taeller * $soejle_br) + $luft;

/*
Og udskriver søjlen
*/
   
    imagefilledrectangle($mit_billede, $x_min, $y_min, $x_max, $y_max, $soejle_farve);

/*
Og sætter en ramme rundt om om søjlen. Hvis du udkommenterer rammen, vil du se, at søjlen
overskriver kanvas-rammen, men søjle-rammen tegner den op igen
*/

    imagerectangle($mit_billede, $x_min, $y_min, $x_max, $y_max, $sort);

/*
Og skriver noget tekst ud på søjle
*/

    $text_bredde = imagefontwidth($etiketfont_str - 1) * strlen($foerste_element);
   
    $x_position = $x_max - $soejle_br / 2 - round($text_bredde / 2);
    $x_position = max(($horisontal_margen + 1), $x_position);
    $lodret_tekst_position = $x_max - $soejle_br / 2 + round($text_hoejde / 3);
    $y_position = $y_max + 3;
   
    $tekst_farve = $sort;
    if($soejle_farve == $moerk_blaa){
        $tekst_farve = $hvid;
    }
   
    imagestringup($mit_billede, $etiketfont_str + 3, $lodret_tekst_position, $y_position - 10, $andet_element, $tekst_farve);
   
    imagestring($mit_billede, $text_bredde, $x_position, $y_position, $foerste_element, $sort);
   
   
}


//Og fremkalder billedet

imageJPEG($mit_billede);
imagedestroy($mit_billede);

?>
Avatar billede intenz Novice
12. maj 2007 - 13:20 #7
Jeg kan ikke se en grund til at opfinde den dybe tallerken flere gange. JpGraph virker fint og der er mulighed for nemt at lave forskellige graf-typer.

Jeg lægger et svar, så kan du afvise hvis du vil.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester