# Zeit-Diagramm erstellen



## data89 (7. Jul 2009)

Hallo,

ich möchte ein Digramm bauen, dass sich so wie die Diagramme (bei 2-Core 2 Diagramme) der CPU-Auslastung im Task-Manager verhält. Der Verlauf wandert immer weiter. Doch irgendwie weiß ich nicht mehr weiter.

Hier was ich bisher habe:

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class DiagrammMain extends JFrame {
	
	private DPanel pan;


	public DiagrammMain() {
		Thread t = new ValueThinker(this);
		t.start();
		
		this.setTitle("Diagramm");
		this.setLayout(new BorderLayout());
		
		this.pan = new DPanel();
		
		this.add(this.pan, BorderLayout.CENTER);
		this.pack();
		this.setSize(200, 100);
		this.setVisible(true);
	}
	
	
	public void value(double v) {
		int a = (int) Math.round(v*100);
		this.pan.update(a);
		this.pan.repaint();
	}
	
	

	public class DPanel extends JPanel {

		int[] werte;
		
		int letzt = 0;
		int cnt = 0;
		int vcnt = 0;
		int[] vv;
		public DPanel() {
			this.werte = new int[10];
			this.vv = new int[200];
			for (int i = 0; i < this.vv.length; i++) {
				this.vv[i] = -1;
			}
		}
		
		public void paintComponent(Graphics g) {
			g.setColor(new Color(0, 0, 0));
			g.fillRect(0, 0, 200, 100);
			g.setColor(new Color(0, 150, 0));
			for (int i = 0; i < 10; i++) {
				g.drawLine(0, i*10, 200, i*10);
			}
			
			for (int i = 0; i < 20; i++) {
				g.drawLine(i*10+this.cnt, 0, i*10+this.cnt, 100);
			}
			g.setColor(new Color(0, 255, 0));
			int i = 1;
			while (this.vv[i] != -1) {
				g.drawLine(i-1, this.vv[i-1], i, this.vv[i]);
				i++;
			}
			
		}
		
		public void update(int a) {

			this.vv[this.vcnt] = a;
			this.vcnt++;
			
			if (this.cnt >= 8) {
				this.cnt = 0;
			} else {
				this.cnt++;
			}
		}
		
		
	}

	
	
	private class ValueThinker extends Thread {
		
		private DiagrammMain main;

		public ValueThinker(DiagrammMain d) {
			this.main = d;
		}
		
		public void run() {
			while (!this.isInterrupted()) {
				double v = Math.random();
				this.main.value(v);
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					return;
				}
			}
			return;
		}
		
	}
	
	
	public static void main(String[] args) {
		new DiagrammMain();
	}
}
```
Über update(...) sollen immer die neuen Werte eingegeben werden können. Doch nun weiß ich nicht mehr weiter, wie ich weitermachen soll.

Habt Ihr ein Paar Tipps?

data89


----------



## SlaterB (7. Jul 2009)

was ist denn deine Frage?
wie du überhaupt die CPU-Belastung messen kannst? 3%, 30%, 300%?
das wüßte ich auch gerne, dazu ist dein Code aber völlig egal, 
das wäre nur ein Befehl, den man kennen müßte, falls es ihn überhaupt gibt,

oder gehts um das Diagramm, dann ist die Art der Werte ja egal,


----------



## data89 (7. Jul 2009)

Achso, es geht mir nicht um die Messung der CPU-Leistung (man brauch ja das Rad nicht zweimal zu erfinden;-)), sondern es geht mir darum eine Klasse zu erstellen, die ein solches Diagramm ist und die ich dann in meinen Projekten benutzen kann *um kontinuierliche zeitliche Prozesse darzustellen*.



> oder gehts um das Diagramm, dann ist die Art der Werte ja egal,


Genau!

Das Grundgerüst steht ja schon (siehe Code). Doch wie bringe ich da nun die Werte drauf? Wie sorge ich dafür, dass sich auch die Werte mit verschieben? Gibt es da Tricks, die man beachten sollte? In welche Richtung sollte der Bereich laufen?

P.S.: Wen es interessiert, wie man mit Java die CPU-Belastung ausliest, der siehe hier: Profiling CPU usage from within a Java application - JavaWorld


----------



## SlaterB (7. Jul 2009)

ich habe dein Programm laufen lassen und da ist doch mit der Zeit schon ordentlich Bewegung, wie im Taskmanager,
funktioniert doch?
nochmal: was ist die Frage?

> Gibt es da Tricks, die man beachten sollte? In welche Richtung sollte der Bereich laufen?

gut, das ist wohl zum Teil nicht sehr konkret 

-----

falls das Array vv und die Anzeige irgendwann voll sind, kannst du ja die Werte im Array verschieben
oder speicherschonender den Startwert verschieben 
(einmal zu sagen 'fange bei Position 5 an' ist schneller als 1000 Werte um 5 Positionen nach links zu setzen)


----------



## data89 (7. Jul 2009)

Ich bekomme es nicht hin, dass die Werte "mit laufen" und dann irgendwann verschwinden. Außerdem muss ja die Durchlaufrichtung von rechts nach links sein, oder?


----------



## SlaterB (7. Jul 2009)

okok, hier diverse Ideen neu eingebaut:

```
public class Test
{
    public static void main(String[] args)
        throws Exception
    {
        new DiagrammMain();
    }


}


class DiagrammMain
    extends JFrame
{

    private DPanel pan;


    public DiagrammMain()
    {
        setTitle("Diagramm");
        setLayout(new BorderLayout());

        this.pan = new DPanel();

        add(this.pan, BorderLayout.CENTER);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200, 100);
        setVisible(true);

        Thread t = new ValueThinker(this);
        t.start();
    }


    public void value(double v)
    {
        int a = (int)Math.round(v * 60);
        this.pan.update(a);
        this.pan.repaint();
    }


    public class DPanel
        extends JPanel
    {

        int[] werte;

        int letzt = 0;
        int cnt = 0;
        int vvIndex = 0;
        int[] vv;
        boolean shiftVVIndex = false;
        int startValuesPos;

        public DPanel()
        {
            this.werte = new int[10];
            this.vv = new int[100];
            for (int i = 0; i < this.vv.length; i++)
            {
                this.vv[i] = -1;
            }
        }

        Color c1 = new Color(0, 0, 0);
        Color c2 = new Color(0, 150, 0);
        Color c3 = new Color(0, 255, 0);

        public void paintComponent(Graphics g)
        {
            g.setColor(c1);
            g.fillRect(0, 0, 200, 100);
            g.setColor(c2);
            for (int i = 0; i < 10; i++)
            {
                g.drawLine(0, i * 10, 200, i * 10);
            }

            for (int i = 0; i < 20; i++)
            {
                g.drawLine(i * 10 - this.cnt, 0, i * 10 - this.cnt, 100);
            }
            g.setColor(c3);
            int i = 1;
            while (i < this.vv.length && this.vv[i] != -1)
            {

                int index1 = ((shiftVVIndex ? vvIndex : 0) + i - 1) % vv.length;
                int index2 = ((shiftVVIndex ? vvIndex : 0) + i) % vv.length;
                int x = 150 + i - 1 - startValuesPos;
                g.drawLine(x, this.vv[index1], x + 1, this.vv[index2]);
                i++;
            }

        }

        public void update(int a)
        {
            this.vv[this.vvIndex] = a;
            if (this.vvIndex >= this.vv.length - 1)
            {
                this.vvIndex = 0;
                shiftVVIndex = true;
            }
            else
            {
                this.vvIndex++;
            }
            if (this.cnt >= 8)
            {
                this.cnt = 0;
            }
            else
            {
                this.cnt++;
            }
            if (startValuesPos < this.vv.length)
            {
                startValuesPos++;
            }
        }


    }


    private class ValueThinker
        extends Thread
    {

        private DiagrammMain main;

        public ValueThinker(DiagrammMain d)
        {
            this.main = d;
        }

        public void run()
        {
            double v = Math.random();
            while (!this.isInterrupted())
            {

                while (true)
                {
                    double newV = v + (Math.random() / 5) - 0.1;
                    if (newV > 0 && newV < 1)
                    {
                        v = newV;
                        break;
                    }
                }
                this.main.value(v);
                try
                {
                    Thread.sleep(100);
                }
                catch (Exception e)
                {
                    return;
                }
            }
            return;
        }

    }


    public static void main(String[] args)
    {
        new DiagrammMain();
    }
}
```


----------



## data89 (7. Jul 2009)

Hallo,

was haltet Ihr von meinem (Teil-)Ergebnis im Anhang? Es ist erstmal durch die Zufallszahlen sehr verwirrend!
*Ach ja, wie nennt man eigentlich genau diese Zwei Diagrammtypen?
*
data89


----------



## kowa (7. Jul 2009)

Sieht doch gut aus!

Würde mich interessieren, wenn du das mit JNI und dem C code auch für mehrere CPUs hinbekommst.

Diagrammtypen? Das eine ist ein Balkendiagramm, das andere ein Kurvendiagramm.


----------



## data89 (8. Jul 2009)

> Diagrammtypen? Das eine ist ein Balkendiagramm, das andere ein Kurvendiagramm.


Hätte ja sein können, dass es da besondere Bezeichnungen gibt!



> Würde mich interessieren, wenn du das mit JNI und dem C code auch für mehrere CPUs hinbekommst.


Eingtlich hatte ich es garnicht im Sinn damit die CPU-Auslastung darzustellen. Ich wollte damit "Kenngrößen" im Netzwerk darstellen (doch dazu habe ich noch einige Fragen, die ich noch stellen muss - aber im Netzwerkunterforum ;-))

Aber nochmal drei Fragen: 
1. Gibt es soetwas wie Anti-Alias für das Kurvendiagramm?
2. Könnte man das noch irgendwie erweitern? (Noch ein Paar besondere Spielereien dranbauen - hat jemand eine Idee?)
3. Die Softwarearchitektur ist ja nich besonders schön: alles an Logik wurde in paintComponent(...) gepackt. Gibt es da elegantere Wege, das zu realisieren?

data89


----------



## Marco13 (8. Jul 2009)

1. Mit 
((Graphics2D)g).setRenderingHint(RenderingHints.KE Y_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
in der paintComponent kann man AntiAliasing einschalten
2. Ja, labels an den Punkten, Zoom- und Scrollfunktion, Mehrere Kurven (ohne dein Programm gesehen zu haben - irgendwas davon wird es sicher noch nicht unterstützen)
3. Ja. (Für eine präzisere Antwort müßt' ich mir's mal ansehen...


----------



## data89 (8. Jul 2009)

> 3. Ja. (Für eine präzisere Antwort müßt' ich mir's mal ansehen...


Also die Architektur ist wie in der von mir geposteten Klasse DPanel realisiert. Und wie kann man die Architektur eleganter gestalten?


----------



## kowa (9. Jul 2009)

Hast du dir mal das ganze unter Linux oder OpenSolaris angesehen?

Ich finde da sieht es vieeeeel besser aus als in WinXP! Die haben da kleinerer Intervalle genommen, also nicht jede Sekunde rutscht der Graph weiter, sondern quasi in Echtzeit. Außerdem ist das heller gestaltet und farblich schöner (Grün auf Schwarz wäre nicht mein Geschmack).


----------

