Antworten auf deine Fragen:
Neues Thema erstellen

horizontales Säulendiagramm Javascript

W

whitestar

Guest

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
 

Duddle

Posting-Frequenz: 14µHz

AW: horizontales Säulendiagramm Javascript

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 die korrekten Ausmaße.


Duddle
 
W

whitestar

Guest

AW: horizontales Säulendiagramm Javascript

@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:
<!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?
 

Duddle

Posting-Frequenz: 14µHz

AW: horizontales Säulendiagramm Javascript

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
 
W

whitestar

Guest

AW: horizontales Säulendiagramm Javascript

@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;
}
 
Zuletzt bearbeitet von einem Moderator:

Duddle

Posting-Frequenz: 14µHz

AW: horizontales Säulendiagramm Javascript

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
 

mindraper

me[code].Java(Script)

AW: horizontales Säulendiagramm Javascript

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:
/* 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(punkte, 10); // 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({name: name, punkte: punkte}); // 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 i = 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 (i < 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 = 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 :)
 
W

whitestar

Guest

AW: horizontales Säulendiagramm Javascript

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?
 

mindraper

me[code].Java(Script)

AW: horizontales Säulendiagramm Javascript

hi

oh, sorry. das hab' ich übersehen :hmpf:

in der function "erstelleDiagramm()" gibt es folgende stelle:
PHP:
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:
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:
// 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:
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 :)
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.565
Beiträge
1.538.067
Mitglieder
67.488
Neuestes Mitglied
Andrew56524
Oben