PieChart labeln

Thanathan

Mitglied
Guten Abend!

Ich habe hier eine Klasse, die mir ein Tortendiagramm mit zwei "Tortenstücken" liefert:

Java:
import javax.swing.*;
import java.awt.*;

// Eine Klasse zum Bereitstellen von Tortendiagrammen.
class TortenDiagramm extends JComponent
{
    private int prozentBenutzt;
    private int prozentVerschwendet;
   
    public TortenDiagramm(int i)
    {
        this.prozentBenutzt = i;
        this.prozentVerschwendet = 100-i;
    }
  
    // überschreibt die JComponent-Methode
    public void paint(Graphics g)
    {
       drawPie((Graphics2D) g, getBounds());
    }
  
    // zeichnet das Diagramm
    void drawPie(Graphics2D g, Rectangle area)
    {
       double kurvenWert = 0.0D;
       int startWinkel = 0;

       // Erstes Tortenstück
       startWinkel = (int) (kurvenWert * 360 / 100);
       int arcWinkel = (int) (prozentBenutzt * 360 / 100);
       g.setColor(Color.magenta);
       g.fillArc(area.x, area.y, area.width, area.height, startWinkel, arcWinkel);
       g.setColor(Color.BLACK);
       g.setFont(new Font("Arial", Font.BOLD, 24));
       g.drawString(""+Integer.toString(prozentBenutzt), area.x, area.y);
       kurvenWert += prozentBenutzt;
      
       // Zweites Tortenstück
       startWinkel = (int) (kurvenWert * 360 / 100);
       arcWinkel = (int) (prozentVerschwendet * 360 / 100);
       g.setColor(Color.yellow);
       g.fillArc(area.x, area.y, area.width, area.height, startWinkel, arcWinkel);
       g.setColor(Color.BLACK);
       g.drawString(""+Integer.toString(prozentVerschwendet), area.x, area.y);
       kurvenWert += prozentVerschwendet;
   }
}

Ich wollte nun noch der Übersicht halber auf jedem Tortenstück darstellen, wie viel Prozent das entsprechende Stück ausfüllt (siehe die g.drawString Methoden), leider funktioniert es scheinbar nicht wie geplant. Sieht jemand, woran das liegen könnte? Danke im Voraus :)

PS: JFreeChart bitte außen vorlassen :D
 

Harry Kane

Top Contributor
area.x und area.y sind die Koordinaten der linken oberen Ecke deines Diagramms. Die Koordinaten, die bei der drawString-Methode übergeben werden, werden allerdings als linke unter Ecke des Textblocks verwendet. Du musst also die y-Koordinate für die drawString-Methode vergrößern.
Ausserdem schreibst du beide Strings an die gleichen Koordinaten.
 

Thanathan

Mitglied
Ah okay, stimmt...

Gut... hm. Fällt dir (oder sonst jemandem) eine Methode ein, die Strings dynamisch dahin zu packen, wo die entsprechenden Tortenstücke hingemalt werden?
Ich müsste ja irgendwie aus g.fillArc(area.x, area.y, area.width, area.height, startWinkel, arcWinkel); passende Koordinaten ziehen, aber wüsste jetzt nicht wie man das geschickt lösen könnte...

Was mir gerade noch einfällt: Gibt es eine Methode, die Schriftgröße dynamisch ans Tortenstück anzupassen, so dass das Label nicht über den Rand hinaus läuft? Ist zwar jetzt nur sekundär, aber sähe schon irgendwie besser aus, denke ich.
 
K

kneitzel

Gast
Dann brauchen wir jetzt einfach einmal die mathematischen Grundlagen. Ist das Diagramm bei Dir ein einfacher Kreis (width = height) oder ist es eine Elipse? Ersteres wäre das einfachste, denn dann könnte man sich alles über einfache Berechnungen im rechtwinkligen Dreieck ausrechnen.

Für unsere Berechnungen machen wir es uns einfach etwas einfacher: Den Mittelpunkt des Diagramms legen wir auf 0,0, d.h. wir malen uns jetzt einen Kreis mit x und y Achse durch den Mittelpunkt.
Nun malen wir uns nur einen Strich unseres Tortenstücks auf als Linie von 0,0 hin zu einem Punkt des Kreises (Einfach im ersten Quadrant, ungefähr 45 Grad Winkel, damit man erst einmal möglichst lange Seiten beim Dreieck bekommt (Das hilft beim bezeichen).

Nun malen wir das Dreieck, d.h. vom Treffpunkt beim Kreis eine Linie zur X oder zur Y Achse. Und schon haben wir ein Dreieck.
Über dieses Dreieck wissen wir:
- Wir haben einen rechten Winkel (zwischen Achse und der letzten Linie
- Wir haben die Länge einer Seite (Die erste Linie hat die Länge vom Radius)
- wir können den Winkel des Dreiecks bei 0,0 berechnen (es ist ja ein Winkel angegeben als Start bzw. Ende. Je nach dem in welchem Quadrant ich bin und wie ich das Dreieck gemalt habe ändert sich die Berechnung etwas.
==> Damit können wir nun über einfache Dreiecksberechnungen die Längen der anderen Seiten berechnen.
==> Je nach Quadrant muss man jetzt halt die Werte positiv oder negativ nehmen.

Als Winkel zur Berechnung nehme ich natürlich (Startwinkel + Endewinkel) / 2 - So erhalte ich über die obrige Berechnung den Punkt auf dem Kreis in der Mitte des Winkels. Dort kann ich den Text dann schreiben.
Evtl. will man noch ein paar weitere Anpassungen vornehmen um alles zu verschönern.
- Ich kann am Radius drehen, damit der Text etwas weiter vom Rand entfernt ist.
- Ich kann evtl. alle Punkte berechnen und für einen minimalen Abstand sorgen. (Evtl. schreibe ich das dann an andere Stellen und male noch einen Strich oder so?)

Diese Ideen sind aber unabhängig von der Berechnung der Punkte.

Konrad
 

Ähnliche Java Themen

Neue Themen


Oben