Zurück   PSD-Tutorials.de > Webbereich > PHP und andere Scriptsprachen


Antwort
 
Themen-Optionen
Alt 20.07.2012, 19:24   #1 Nach oben scrollen
Newbie
Newbie
 

Registriert seit: 19.07.2012
Beiträge: 4

horizontales Säulendiagramm Javascript


Hallo zusammen,

ich komme bei folgendem Programm nicht weiter.
Es soll anhand von Prüfungsdaten ein Diagramm erstellt werden.
Für jeden Teilnehmer eine Säule. Die Höhe entspricht dem Verhältnis seiner erreichten Punkte zum Maximum. (also bei 5 von 15 Punkten, 1/3 der Höhe)
Ich habe bisher folgenden Code zum Einlesen der Daten:

Code:
function erfasseDaten() {
    var name = "";
    var erreichtePunkte = 0;
    var maxPunkte = 0;
    var namen = [];
    var punktzahlen = [];
    
    while (name = prompt("Geben Sie den Namen des Prüfungsteilnehmers ein!", " ")) {
        name = name.replace(/^\s+/,"");
        if (!isNaN(name) || name == "") {
            alert("Sie müssen einen gültigen Namen eingeben!");
        }
        else {
            namen.push(name);
            while (erreichtePunktzahl = prompt("Geben Sie die erreichte Punktzahl des Teilnehmers ein!", " ")) {
                erreichtePunktzahl = erreichtePunktzahl.replace(/^\s+/,"");
                if (isNaN(erreichtePunktzahl) || erreichtePunktzahl == "") {
                    alert("Sie müssen eine gültige Zahl eingeben!");
                }
                else {
                    punktzahlen.push(erreichtePunktzahl);
                    break;
                }
            }
            maxPunkte = prompt("Geben Sie die maximal erreichbare Punktzahl ein!");
            maxPunkte = parseInt(punktzahlen / maxPunkte * 100);
        }
    }
}
Jetzt müsste halt, wie schon gesagt, anhand der eingegebenen Daten ein Säulendiagramm erstellt werden. Ohne Verwendung von externen Bibliotheken. Ich weiss nur leider nicht wie ich das angehen soll, das zu realisieren. Kann mir da jemand weiterhelfen?
Danke!

Gruss
  Mit Zitat antworten


Alt 20.07.2012, 21:34   #2 Nach oben scrollen
Posting-Frequenz: 14µHz
Premium-SupporterPremium-SupporterPremium-SupporterPremium-SupporterPremium-Supporter
 
Benutzerbild von Duddle
 

Registriert seit: 03.02.2006
Ort: Dresden
Beiträge: 3.225

Ich nehme an, das ist eine Art Schulaufgabe o.ä., sonst könnte ich den Verbot von externen Bibliotheken nicht verstehen. Deshalb bin ich gezielt vage in meiner Antwort, schließlich sollst du ja etwas aus der Übung lernen:

Ein Säulendiagramm besteht aus mehreren Rechtecken, dessen jeweilige Ausmaße ihren Wert anzeigen.
Ein Rechteck ist eine Fläche mit Höhe und Breite. Um ein Rechteck anzuzeigen, kannst (abgesehen von Bildern) einfach ein <div>-Element erzeugen und entsprechend farbig markieren. Diesem kannst du sehr einfach per CSS Höhe und Breite geben. Diese Parameter wiederum kannst du mit JavaScript beeinflussen/ändern.

Kurz: erzeuge ein paar <div>s und gib ihnen per JS die korrekten Ausmaße.


Duddle
__________________
»To a cosmologist, a hundred thousand light-years rounds down to zero.« - RobotRollCall
  Mit Zitat antworten
Alt 20.07.2012, 22:36   #3 Nach oben scrollen
Photonensammler
Spezial-SupporterSpezial-SupporterSpezial-SupporterSpezial-Supporter
 
Benutzerbild von Digicam
 

Registriert seit: 27.08.2006
Ort: D-68723
Beiträge: 1.897
Kamera: Canon EOS 500D, Tamron SP AF 17-50mm 2,8 XR Di II VC

Vielleicht hilft Dir das weiter:
http://mawosoft.de/tips_js_chart.htm
__________________
Meine Bilder auf flickr und Panoramio
Informationsfluss im Forum verbessern
Wenn Dir Motive fehlen, geh' ohne Kamera auf die Straße und Du wirst 1.000 Motive finden.
  Mit Zitat antworten
Alt 21.07.2012, 17:52   #4 Nach oben scrollen
Newbie
Newbie
Themenstarter
 

Registriert seit: 19.07.2012
Beiträge: 4

@Duddle:
Ich habe von einem Freund ein Lernheft bekommen, da ich privat Javascript lernen wollte. Aus der Schule bin ich schon eine Weile raus. Ich mache gerade diese Aufgabe zur Übung, in der keine externe Bibliotheken erlaubt sind. Das wollte ich dann auch versuchen so umzusetzen. Aber daraus was lernen möchte ich natürlich schon

...also ich habe nun folgenden Code.

HTML
HTML-Code:
<!DOCTYPE html>

<html>
<head>
    <title>Prüfungsauswertung</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" type="text/css" href="prüfungsauswertung.css"/>
    <script type="text/javascript" src="prüfungsauswertung.js"></script>
</head>

<body>
    <button onclick="erfasseDaten()">Teilnehmer hinzufügen</button>
    <h4>Diagramm</h4>
    <div id="diagram">
        <div id="bar"></div>
        <div id="beschriftung"></div>
    </div>
</body>
</html>
CSS
Code:
body {
    font-family: verdana;
}

h4 {
    color: #0000ff;
}
 
#diagram {
    width: 600px;
    border: 1px solid #000000;
    padding: 5px;
}
            
#bar {
    border: 1px solid #000000;
    width: 20px;
    background-color: green;
    font-weight: bold;
    color: #FFFFFF;
    text-align: center;
    display: block;
    font-size: 8pt;
}
            
#beschriftung {
    width: 100%;
    display: block;
    margin: 10px 0;
    font-size: 9pt;
    font-weight: bold;
    color: #000000;
}
JavaScript
Code:
function erfasseDaten() {
    var name = "";
    var erreichtePunkte = 0;
    var maxPunkte = 0;
    var namen = [];
    var punktzahlen = [];
    
    while (name = prompt("Geben Sie den Namen des Prüfungsteilnehmers ein!", " ")) {
        name = name.replace(/^\s+/,"");
        if (!isNaN(name) || name == "") {
            alert("Sie müssen einen gültigen Namen eingeben!");
        }
        else {
            namen.push(name);
            while (erreichtePunktzahl = prompt("Geben Sie die erreichte Punktzahl des Teilnehmers ein!", " ")) {
                erreichtePunktzahl = erreichtePunktzahl.replace(/^\s+/,"");
                if (isNaN(erreichtePunktzahl) || erreichtePunktzahl == "") {
                    alert("Sie müssen eine gültige Zahl eingeben!");
                }
                else {
                    punktzahlen.push(erreichtePunktzahl);
                    break;
                }
            }
            maxPunkte = prompt("Geben Sie die maximal erreichbare Punktzahl ein!");
            maxPunkte = parseInt(punktzahlen / maxPunkte * 100);
        }
    }
    erstelleDiagramm(namen, punktzahlen, maxPunkte);
}

function erstelleDiagramm(beschr, wert, maxWert) {
    document.getElementById("bar").style.height += wert / maxWert * 100;
    document.getElementById("beschriftung").innerHTML += beschr;
}
Die Beschriftung wird zwar angezeigt, aber es wird leider kein Balken erzeugt. Dieser sollte ja durch die Eingabe der Werte automatisch erzeugt werden. Wo liegt denn mein Fehler?
  Mit Zitat antworten
Alt 21.07.2012, 18:48   #5 Nach oben scrollen
Posting-Frequenz: 14µHz
Premium-SupporterPremium-SupporterPremium-SupporterPremium-SupporterPremium-Supporter
 
Benutzerbild von Duddle
 

Registriert seit: 03.02.2006
Ort: Dresden
Beiträge: 3.225

Dann lade dir erstmal FireBug für den Firefox runter, damit wird das debuggen deutlich einfacher. Darin kannst du dir u.a. die ganzen Objekte genau anschauen und ausgeben lassen, selektiv CSS-Eigenschaften de/aktivieren usw.

Du machst mehrere Dinge seltsam: erstens solltest du wohl solange die Ausgabe nicht stimmt mit statischen Testdaten arbeiten, damit du die nicht immer eingeben musst. Sobald die korrekt angezeigt werden, kannst du da Variablen und Nutzereingaben reinbringen.

Zweitens übergibst du an erstelleDiagramm() drei Parameter: beschr ist ein String, wert ein Array von Strings, maxWert ist eine Zahl. Kritisch ist dabei das Array, besonders weil du damit rechnen willst.
Entweder musst du über alle übergebenen Werte durchlaufen und für jeden Einzelwert etwas berechnen/tun, oder du nimmst vom Array den n-ten Eintrag (sinnvoll wäre n=0), oder du übergibst vorher schon den korrekten Wert statt dem Array an die Funktion.

Drittens gibst du dem height-Attribut einen festen Wert (bzw. hast es vor), aber ohne Einheit. Ein Element mit "height:50;" ist nicht das gleiche wie "height:50px;" oder "height:50%;" und nur die letzten beiden Versionen funktionieren.

Viertens: sowas wie
Code:
maxPunkte = parseInt(punktzahlen / maxPunkte * 100);
ist wirklich seltsam. Denk über die Datentypen der einzelnen Variablen nach, dann solltest du sehen dass in dieser Zeile einige Fehler stecken.

Zusammengefasst also: fang von der anderen Seite an. Konstruiere ein statisches Diagramm mit normalem HTML und CSS. Dann schreib eine Funktion zum Verändern dieser Werte. Dann zum Erzeugen / Verändern des HTML-Teils. Danach kannst du diese Funktion parametrisieren und mit Nutzereingaben füllen.


Duddle
__________________
»To a cosmologist, a hundred thousand light-years rounds down to zero.« - RobotRollCall
  Mit Zitat antworten
Alt 22.07.2012, 18:15   #6 Nach oben scrollen
Newbie
Newbie
Themenstarter
 

Registriert seit: 19.07.2012
Beiträge: 4

@Duddle
ich möchte dich nicht nerven mit dem Programm, aber ich komme da einfach nicht richtig weiter. Es wird zwar jetzt ein Balken richtig erzeugt, aber nur für den ersten eingegebenen Teilnehmer. Sobald ich weitere Teilnehmer erfasse, wird zwar der Name notiert aber kein Balken erzeugt. Es soll ja automatisch für jeden erfassten Teilnehmer ein Balken erzeugt werden. Insgesamt so viele Balken wie auch Teilnehmer eingetragen wurden.

JavaScript Code:

Code:
function erfasseDaten() {
    var name;
    var erreichtePunktzahl = 0;
    var maxPunkte = 0;
    var namen = [];
    var punktzahlen = [];
    
    while (name = prompt("Geben Sie den Namen des Prüfungsteilnehmers ein!", " ")) {
        name = name.replace(/^\s+/,"");
        if (!isNaN(name) || name == "") {
            alert("Sie müssen einen gültigen Namen eingeben!");
        }
        else {
            namen.push(name);
            while (erreichtePunktzahl = prompt("Geben Sie die erreichte Punktzahl des Teilnehmers ein!", " ")) {
                erreichtePunktzahl = erreichtePunktzahl.replace(/^\s+/,"");
                if (isNaN(erreichtePunktzahl) || erreichtePunktzahl == "") {
                    alert("Sie müssen eine gültige Zahl eingeben!");
                }
                else {
                    punktzahlen.push(erreichtePunktzahl);
                    break;
                }
            }
            maxPunkte = prompt("Geben Sie die maximal erreichbare Punktzahl ein!");
            maxPunkte = parseInt(erreichtePunktzahl / maxPunkte * 100) + "px";
        }
    }
    erstelleDiagramm(namen, maxPunkte);
}

function erstelleDiagramm(beschr, maxWert) {
    document.getElementById("bar").style.height += maxWert;
    document.getElementById("beschriftung").innerHTML += beschr;
}

Geändert von whitestar (22.07.2012 um 18:20 Uhr).
  Mit Zitat antworten
Alt 22.07.2012, 18:29   #7 Nach oben scrollen
Posting-Frequenz: 14µHz
Premium-SupporterPremium-SupporterPremium-SupporterPremium-SupporterPremium-Supporter
 
Benutzerbild von Duddle
 

Registriert seit: 03.02.2006
Ort: Dresden
Beiträge: 3.225

Wenn es mich nerven würde, würde ich nicht antworten.

Du scheinst aber meine Antwort nicht genau gelesen zu haben, da du immer noch wie wild Datentypen durcheinander wirfst und hoffst dass es irgendwie gut geht (bzw. erst garnicht verstehst, dass das ein Problem ergibt).

namen ist ein Array. Du übergibst an erstelleDiagramm() also ein Array. In der Funktion selbst behandelst du den Parameter aber wie einen String. Das ist ein Fehler.

maxPunkte ist nach dem prompt() ein String. In der direkt folgenden Zeile behandelst du es wie einen Zahlwert. Das ist ein Fehler. Oder zumindest eine Unsauberkeit.

Das height-Attribut vom style-Objekt des Elementes mit ID "bar" ist ein String. Strings können nicht einfach addiert werden (bzw. der Additions-Operator bedeutet in dem Fall Konkatenation).

Schau dir im FireBug an, welche Daten an erstelleDiagramm() übergeben werden. Dann simuliere die nächsten Schritte des Algorithmus von Hand mit statischem HTML. Du solltest dabei auf die große Hürde stoßen, auf die ich mehrmals hingewiesen habe.


Duddle
__________________
»To a cosmologist, a hundred thousand light-years rounds down to zero.« - RobotRollCall
  Mit Zitat antworten
Alt 22.07.2012, 22:56   #8 Nach oben scrollen
me[code].Java(Script)
MemberMember
 
Benutzerbild von mindraper
 

Registriert seit: 12.08.2007
Ort: Zuhause
Beiträge: 188
Verwendet: Adobe CS5 (PS/I/ID/Bridge/FL), Sublime Text 2, NetBeans, Blender, Pencil

hi

um dir den spaß an der sache nicht gänzlich zu verleiden, gebe ich mal mehr hilfestellung. außerdem gibt es menschen, die mehr durch "nachahmen" lernen als durch ausprobieren.

allerdings solltest du dich hinsetzen und den code durcharbeiten, bis du wirklich verstehst was passiert! und, so wie Duddle schon sagte, solltest du dich wirklich hinsetzen und datentypen lernen. in deinem code sind (natürlich durch dein "stadium" bedingt) einige datentypenbasierte fehler bzw. recht unsinnige prüfungen (stichwort: isNaN()).

falls du eher zu menschen gehörst die "nachahmen":

PHP-Code:
/* GRUNDSÄTZLICHE ÜBERLEGUNGEN
 * ----------------------------------------------------
 * 1) bei klick auf den button eine neue person anlegen
 * 1.1) namen erfragen
 * 1.2) erreichte punktzahl erfragen
 * 1.3) daten säubern und prüfen
 * 1.4) daten speichern
 *
 * 2) neuen balken erzeugen
 * 2.1) container-element auswählen
 * 2.2) neuen balken in container erzeugen
 * 2.3) größe und beschriftung des balkens eintragen
 *
 * 3) zu (1) zurück
 * ---------------------------------------------------- */

 // globale variablen
 
var teilnehmer = []; // teilnehmerliste, die bei jedem klick erweitert wird
 
var maxPunkte 200// maximal erreichbare punktzahl (beispielwert), diese ändert sich ja nicht pro teilnehmer
 
var balkenHoehe 20// höhe des balkens pro teilnehmer

// daten erfassen
function erfasseDaten () {
    var 
name window.prompt('Bitte geben Sie den Namen des Prüflings ein:'); // prüflingsnamen erfragen
    
var punkte window.prompt('Bitte geben Sie die erreichte Punktzahl des Prüflings ein:'); // punktezahl erfragen

    // daten säubern
    
name name.replace(/\s+/g''); // alle leerzeichen in name entfernen
    
punkte parseInt(punkte10); // punkte in ganzzahl umwandeln mit dezimaler basis

    // daten prüfen
    
if (name !== '' && !isNaN(punkte)) { //wenn name kein leerer string ist und punkte ein numerischer wert... 
        
teilnehmer.push({namenamepunktepunkte}); // daten speichern

        /* die daten werden als object jedesmal an das ende
         * der teilnehmerliste gehängt. bei jedem erzeugen
         * des balkendiagrammes wird die teilnehmerliste
         * durchlaufen und pro teilnehmer der name und die
         * anzahl der erreichten punkte abgefragt. aus diesen
         * daten wird dann der balken des teilnehmers erstellt.
        */
    
}

    
erstelleDiagramm(); // funktion zum erstellen des diagrammes aufrufen
};

// diagramm erstellen
function erstelleDiagramm () {
    var 
0// zählevariablen für eine schleife zum durchlaufen der teilnehmerliste
    
var len teilnehmer.length// länge der teilnehmerliste, dient dem beenden der schleife
    
var balken null// platzhaltervariable, wird bei jedem schleifendurchlauf ein neuer balken

    // 2.1
    
var container document.getElementById('diagramm'); // container-element holen

    // schleife zum durchlaufen der teilnehmerliste
    
while (len) {
        
// 2.2
        
balken document.createElement('div'); // dieses div wird der balken
        
balken.style.height balkenHoehe 'px'// den balken 20px hoch machen
        
balken.style.marginBottom '5px'// der balken hat einen außenabstand nach unten von 5px

        // daten von teilnehmer 1, 2, 3, ... auslesen
        
balken.style.width = ((teilnehmer[i].punkte maxPunkte) * 100) + '%'// ... breite berechnen
        
balken.innerHTML = ['<p>'teilnehmer[i].name'</p>'].join(''); // ... namen im p-tag in den balken schreiben

        // balken in container einfügen, immer als letztes element
        
container.appendChild(balken);

        
// schleifenzähler um 1 erhöhen
        
i+1;
    }
}; 
ich denke ich habe alle schritte ausführlich auskommentiert, es sollte also prinzipiell alles verständlich sein.

wie gesagt, nur abtippen nützt dir nichts. allerdings vermute ich, dass du den code so oder so durchgehst und für dich ausarbeitest, wo denn grundsätzliche unterschiede sind, welche teile du nicht bedacht hast oder wo du dinge vielleicht anders machen würdest als ich.

hoffe das hilft
__________________
Nichts ist so gerecht verteilt wie der Verstand.
Jeder denkt, er hätte genug.
  Mit Zitat antworten
Alt 25.07.2012, 14:00   #9 Nach oben scrollen
Newbie
Newbie
Themenstarter
 

Registriert seit: 19.07.2012
Beiträge: 4

das war schon sehr hilfreich, danke.

@mindraper
der balken wird allerdings immer nur einmal erzeugt. Wo liegt denn da noch der Fehler?
Eine letzte Frage habe ich noch. Wie kann man jeden Balken, der erzeugt wird (anzahl ist ja anfangs unbekannt), in einer anderen Farbe darstellen?
  Mit Zitat antworten
Alt 25.07.2012, 23:12   #10 Nach oben scrollen
me[code].Java(Script)
MemberMember
 
Benutzerbild von mindraper
 

Registriert seit: 12.08.2007
Ort: Zuhause
Beiträge: 188
Verwendet: Adobe CS5 (PS/I/ID/Bridge/FL), Sublime Text 2, NetBeans, Blender, Pencil

hi

oh, sorry. das hab' ich übersehen

in der function "erstelleDiagramm()" gibt es folgende stelle:
PHP-Code:
var container document.getElementById('diagramm'); 
damit gleiche balken nicht mehrfach eingesetzt werden, musst du "container" leeren, bevor die neuen balken erzeugt werden (also VOR der schleife). damit du auch selbst etwas tust, belasse ich es mal damit – letzten endes willst du es ja lernen und man lernt sprachen nur, wenn man sie auch nutzt an hinweisen ist das eigentlich schon mehr als genug.

nur noch ein tipp: am einfachsten geht das leeren mit innerHTML = '';

beim einfärben der balken kann ich dir helfen. zunächst einmal: farben können mit css entweder über hexadezimale werte, mit definierten schlüsselwörtern oder mit rgb-werten gesetzt werden. für das erzeugen von zufälligen farben ist letzteres das einfachste.

um rgb-farbwerte in css zu setzen, wird "rgb(ROTANTEIL, GRÜNANTEIL, BLAUANTEIL)" geschrieben. jeder anteil eines farbkanals kann zwischen 0 und 255 liegen.
den anteil mit javascript zu generieren ist eigentlich ganz einfach:

PHP-Code:
var rot Math.floor(Math.random() * 255);
var 
gruen Math.floor(Math.random() * 255);
var 
blau Math.floor(Math.random() * 255); 
erklärungen zum Math-Objekt und seinen methoden findest du z. b. hier

für den geplanten ansatz ist es einfacher, das erzeugen der farbkanalanteile in eine function auszulagern, die jedesmal den kompletten css farbwert auf das balkenelement setzt, wenn dieses erzeugt wird:

PHP-Code:
// zufälligen farbwert
function getRandomColor () {
    
// gibt "rgb(FARBWERT, FARBWERT, FARBWERT)" zurück
     
return ['rgb('Math.floor(Math.random() * 255), ', 'Math.floor(Math.random() * 255), ', 'Math.floor(Math.random() * 255), ')'].join('');
 }; 
jetzt musst du nur noch die "erstelleDiagramm()"-function anpassen. dazu schreibst du innerhalb der darin liegenden while-schleife folgendes:

PHP-Code:
balken.style.height balkenHoehe 'px'// den balken 20px hoch machen 
balken.style.marginBottom '5px'// der balken hat einen außenabstand nach unten von 5px

// !!!!!!!!!!!!!!!!!!!!!!! NEU !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
balken.style.backgroundColor getRandomColor(); // zufallsfarbwert als balkenhintergrund
// !!!!!!!!!!!!!!!!!!!!!!! ENDE NEU !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// daten von teilnehmer 1, 2, 3, ... auslesen 
balken.style.width = ((teilnehmer[i].punkte maxPunkte) * 100) + '%'// ... breite berechnen 
hoffe das hilft nochmal
__________________
Nichts ist so gerecht verteilt wie der Verstand.
Jeder denkt, er hätte genug.
  Mit Zitat antworten
Antwort


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Horizontales Dropdown AxelM (X)HTML & CSS 4 28.02.2012 10:40
Horizontales und vertikales Zentrieren von DIV's Crackp0t (X)HTML & CSS 8 21.03.2010 15:16
horizontales menü mit untermenü für ie6 afr0kalypse (X)HTML & CSS 2 05.08.2009 16:13
horizontales Menü Can_nim Trash 2 30.07.2008 22:01
Horizontales Menu BillaB (X)HTML & CSS 3 21.10.2007 13:46