Wie lade ich eine CategoryDataset aus XML ins JFreeChart?

Faiza

Mitglied
Hallo zusammen,

Zuerst möchte ich erwähnen dass ich sehr sehr sehr lange in Google gesucht habe, leider bin ich nicht fündig geworden.
Ich möchte meine Attribute von XML auslesen in einer JFreeChart auslesen, in Form von Dataset.
z.B ich möchte ein LineChart ausgeben (siehe Anhang) von den Attributen die in meine XML Datei stehen, soll diesen Chart befüllen.
Ich habe eine passende Query dazu allerdings dies läuft in Backend und funktioniert einwandfrei.

Mein Chart soll zum Beispiel so aussehen wie in den Anhang.

So siehst mein Programm momentan aus.

Java:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

@SuppressWarnings("serial")
public class ComponentPanel extends JFrame implements ActionListener {
	
	Connection con;
	
	private static final String 
	tablename = "LOC", // just an example 
	valuenames = "reportingDate";// just an example 
	private CategoryDataset dataset;
	String name;
	public ComponentPanel() throws Exception {
		super("OptimISE Component Model");

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
		setSize(new Dimension(250, 270));
		add(createComponentPanel(), getLayout());

		pack();
		setVisible(true);
	}

	private Component createComponentPanel() throws Exception {

		// ---- Panel which holds the Buttons ----		
		JPanel p = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
		p.setBorder(BorderFactory.createTitledBorder(null, "",TitledBorder.DEFAULT_JUSTIFICATION,
				TitledBorder.DEFAULT_POSITION,new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));

	      // ---- Parse XML file ----
		DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document doc = db.parse(getClass().getResourceAsStream("OptimISEGuiModel.xml"));
		
		// ---- Get the root element ----		
		System.out.println("Root " + doc.getDocumentElement().getNodeName());

	      // ---- Get list of nodes to given MainButton ----
		NodeList mainButtons = doc.getElementsByTagName("MainButton");

		// ---- Run through the MainButton and all MainButton which exists in XML file		
		for (int i = 0; i < mainButtons.getLength(); i++) {
			Element mainButton = (Element) mainButtons.item(i);
			
			// ---- Run through the MainButton and fetch all element which are taged as ChartName			
			Element chartName = (Element) mainButton.getElementsByTagName("ChartName").item(0);
			name = chartName.getTextContent();
			System.out.println("ChartName = " + name);

			// ---- Buttons on the Panel are created here ----			
			JButton btn = new JButton(name);
			btn.setPreferredSize(new Dimension(180, 30));
			btn.setActionCommand(name);
			p.add(btn);

			// ---- NodeList is created which fetches all the tagged Attributes ----  			
			NodeList nodeLst = doc.getElementsByTagName("MainButton");
			
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);

				// ---- Fetch the Attributes which is tagged ----
				if (fstNode.hasAttributes()) {
					NamedNodeMap map = fstNode.getAttributes();
				}
			}
		}

		return p;
	}
	
	private JFreeChart createChart(){
		JFreeChart chart = ChartFactory.createLineChart(
				"",
				"",
				"",
				dataset, 
				PlotOrientation.VERTICAL, 
				true, 
				true, 
				false);
		return chart;
	}
	
	//later the action will be added to the buttons 		
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals( name + "LOC")) {
			// ---- Execute when button is pressed ----
			System.out.println("You clicked the button " + name);
			final LOC test = new LOC("");
			test.pack();
			setDefaultCloseOperation(EXIT_ON_CLOSE);
			test.setVisible(true);
		}
		}
	}

[XML]<?xml version="1.0" encoding="UTF-8"?>

<OptimISEGuiModel>
<MainButton>
<ChartName>LOC</ChartName>
<charttype basetype="Cartesian">
<chartrenderer useAlertColors="true" type="LineChart" mode="LineChart"> </chartrenderer></charttype>
<legend visible="true" position="right" background="white" foreground="" />
<labelrenderer color="" offset= "" rotation= "" visible=""/>
<datasetlegend match="" display="Arch" showValue="true" showStart=" (total: " showEnd=")"/>
<graph name="Arch" value="50" color="0x808080"/>
<datasetlegend match="" display="Other" showValue="true" showStart= " (total: " showEnd=")" />
<graph name="Other" value="50" color="0xCC3333"/>
<datasetlegend match="" display="Model" showValue="true" showStart=" (total: " showEnd=")"/>
<graph name="Model" value="50" color="0x0000FF"/>
<datasetlegend match="" display="App" showValue="true" showStart=" (total: " showEnd=")" />
<graph name="App" value="50" color="0x009F6B"/>


<!-- not sure if this is going to work -->
<xaxis>
<annotation match="App" text="ReportingDate"/>
</xaxis>
<yaxis> <annotation match="" text=""/></yaxis>


<Archcolor> value="Grey"</Archcolor>
<Othercolor> value="Red"</Othercolor>
<Modelcolor> value= "Blue"</Modelcolor>
<Appcolor> value="Green"</Appcolor>
</MainButton>


<MainButton>
<ChartName>Sir Statistics</ChartName>
</MainButton>


<MainButton>
<ChartName>Test Statistics</ChartName>
</MainButton>

<MainButton>
<ChartName>Issue</ChartName>
</MainButton>

<MainButton>
<ChartName>Rappidd</ChartName>
</MainButton>
</OptimISEGuiModel>
[/XML]
 

Anhänge

  • Screenshot-OptimISE R1.0 LOC.jpg
    Screenshot-OptimISE R1.0 LOC.jpg
    104,5 KB · Aufrufe: 36
hmm, es läuft doch oder? mit mainButtons liest du schon erfolgreich die zugehörigen Elemente aus?
immer weiter, jedes einzelne benötigte Element in eine Variable übertragen und später an richtige Stelle in die Chart-Konfiguration,
das sind vielleicht noch hunderte Zeilen Code, Arbeit Arbeit Arbeit, aber kein direktes Problem, was genau ist da jetzt die Frage?


die einzelnen Datenwerte sind in der gegebenen XML-Datei nicht aufgeführt, herbeizaubern kann man die nicht
 
ja ja laufen tut es prima... das stimmt auch mainButtons funktionieren auch erfolgreich.
Mein Problem ist dass ich meine Ergebnisse von mainButton nicht auf der Konsole sondern in eine JFreeChart sehen möchte.
Ich weiß leider nicht wie ich die Information aus der XML Datei in JFreeChart rein hauen kann 🙁 damit es so aussieht wie in das Bild (siehe Anhang von Oben)
 
nun, zunächst brauchst du anscheinen einen JFreeChart-Lehrkurs, vergiss die XML-Datei komplett
und versuche nur mit Java-Befehlen, die Chart so genau wie möglich nachzubauen,
wobei da mehr als das Datenset und Label + Farben für die Renderer gar nicht zu tun ist,

kopiere dir Beispiele von
Line ChartChartJava
und erweitere diese um mehr Linien, formatiere die Renderer usw.

immer noch stellst du keine konkreten Fragen wie 'wie setze ich Renderer für Linie 2 auf Farbe Rot?',
wobei ich auch bezweifle, dass ich das alles haarklein beantworten würde,
erstmal Tage und Wochen alle Möglichkeiten von JFreeChart kennenlernen, viele Beispiel anschauen
 
Eigentlich kenne ich mich schön mit JFreeChart aus. Ich wollte die setting für den JFreeChart aus XML steuern. Ich brauche es für Leute die sich mit Java nicht auskennen, damit sie später Sachen wie Farbe, Background etc in XML ändern können.
Also meine Konkrete Frage: Wie kriege ich die Attribute von XML in JFreeChart geliefert? Es soll später so aussehen wie das Bild oben

Ich habe mir überlegt das hier zu verwenden
JFreeChart: XML Bar Chart Demo : XML ChartChartJava
aber ich habe keine URL sondern ein FILE


Das Code für das bild lautet:

[Java]package gtssvn.ise.tool.mgmt.optimise;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.JFrame;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.RectangleEdge;

/**
* This Class creates a Chart for Line of Code
*
* @author zafafai
*
*/

public class JChartCodeCountLOC extends JFrame {

Connection con;

// initialize the JTable
public JChartCodeCountLOC (final String title)
{
super("OptimISE R1.0 LOC");
final CategoryDataset dataset = createDataset();
final JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(1500, 800));
setContentPane(chartPanel);

}

/**
* Gets the data from Databases named CodeCount.
*
* @return The dataset.
*/

private CategoryDataset createDataset()
{
try
{
Sql sql = new Sql();
ResultSet set = null;
Connection con;
con = sql.getCodeCountConnection();
set = con.createStatement().executeQuery("SELECT reportingDate, domainName,overallpLoc, " +
"overallLLOC FROM DomainTotalsPerReportingDate order by reportingDate");

final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
Date temp = Date.valueOf("2011-12-31");

while(set.next())
{
Date date = set.getDate("reportingDate");

if (date.before(temp))
{
dataset.addValue(set.getBigDecimal("overallLLoc"),
set.getString("domainName"),
set.getDate("reportingDate"));
}
}
con.close();
return dataset;
}

catch (SQLException e1)
{
e1.printStackTrace();
}
catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
return null;
}



/**
* Here the chart is drawn
* @param dataset
* @return
*/
private JFreeChart createChart(final CategoryDataset dataset)
{

// create the chart
final JFreeChart chart = ChartFactory.createLineChart(
"", // chart title
"", // domain axis label
"", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
true, // include legend
false, // tooltips
false // urls
);

// get a reference to the plot for further customisation...
CategoryPlot plot = chart.getCategoryPlot();
NumberAxis rangeAxis = (NumberAxis)plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
CategoryAxis xAxis = (CategoryAxis)plot.getDomainAxis();
xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);

chart.setBackgroundPaint(Color.white);
plot.setBackgroundPaint(Color.white);
plot.setRangeGridlinePaint(Color.black);
plot.getRenderer().setSeriesPaint(0, Color.lightGray);


// customise of range axis
// final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();

// set the legend on the right Side
LegendTitle legend = chart.getLegend();
legend.setPosition(RectangleEdge.RIGHT);

// // customise the rendererre
final LineAndShapeRenderer renderer1 = (LineAndShapeRenderer) plot.getRenderer();
renderer1.setStroke(new BasicStroke(3f, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_BEVEL));

final GradientPaint gp0 = new GradientPaint(0.0f, 0.0f, Color.green,
0.0f, 0.0f, Color.green);
final GradientPaint gp1 = new GradientPaint(0.0f, 0.0f, Color.darkGray,
0.0f, 0.0f, Color.darkGray);
final GradientPaint gp2 = new GradientPaint(0.0f, 0.0f, Color.blue,
0.0f, 0.0f, Color.blue);

final GradientPaint gp3 = new GradientPaint(0.0f, 0.0f, Color.red,
0.0f, 0.0f, Color.red);


return chart;
}






}


[/code]
 
Zuletzt bearbeitet:
das ist nicht konkret genug, da ich das schon angesprochen hatte,
mit NodeList und Co bekommst du die Daten (oder wo liegt da konkret das Problem?)
Color x = getNextNode().getColor()
chart.setzeFarbeInRender(x);

das sind alles Fantasie-Befehle,
hängt davon ab wie du die Nodes durchläufst, (einer nach dem anderen oder speziell nach Typ suchen)
hängt davon ab wie du die Chart machst, ob da schon ein Objekt vor dem Parsen des XML besteht oder erst später, ob Klassenattribut, Parameter usw.

> aber ich habe keine URL sondern ein FILE

die URL wird dort auch nur aus einem Dateipfad erstellt,
FILE -> Dateipfad -> URL,
wird aber nicht helfen, denn du hast ja ein anderes Format und in deinem XML geht es nicht um die Daten sondern um die Renderer
 
Zuletzt bearbeitet von einem Moderator:
Ich verstehe nicht so ganz das Problem... :bahnhof:

Wieso nicht die URL benutzen?
Wenn Du unbedingt stattdessen File benutzen möchtest, sollte etwas in der Richtung gehen (ungetestet)

Java:
        CategoryDataset dataset = null;
        final File f = new File("blah.xml");

        try {
            final InputStream in = new FileInputStream(f);
            dataset = DatasetReader.readCategoryDatasetFromXML(in);
        }
        catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        }

Aber vielleicht hab ich auch das Problem nicht verstanden 😉

Edit: zu laaaaangsam 😉
 
ich glaube ich versuche das ein bissen anders zu erklären. Vielleicht reden wir an einander vorbei oder ich habe es nicht gut genug erklärt 😳

mit NodeList und Co bekommst du die Daten (oder wo liegt da konkret das Problem?)
Ja die Daten bekomme ich, wie kriege ich diese Daten in einer Chart(JFreeChart) über gegeben?
Die Eigenschaften sollen ausschließlich von XML über genommen werden. Sachen wie
Color x = getNextNode().getColor()
macht kein Sinn weil ich die Eigenschaft Color in Java geschrieben habe.


hängt davon ab wie du die Chart machst,

Ist JFreeChart eine gute Lösung oder soll ich eine andere Chart variante wählen??

ob da schon ein Objekt vor dem Parsen des XML besteht oder erst später

würde mir getter und setter da weiter helfen oder soll ich PoJo's verwenden?
 
> Ja die Daten bekomme ich, wie kriege ich diese Daten in einer Chart(JFreeChart) über gegeben?

zuviel auf einmal, grundsätzlich hast da von Natur gegeben ZWEI Schritte,
erst 'irgendwas' aus dem XML rausbekommen,
und zweitens davon nahezu unabhängig diese Information dann weiterverarbeiten,
zunächst System.out.println(), später dann sicherlich an die Chart übergeben

vergleiche dazu meine zwei Codezeilen:
Color x = getNextNode().getColor() // 1. Schritt
chart.setzeFarbeInRender(x); // 2. Schritt

> macht kein Sinn weil ich die Eigenschaft Color in Java geschrieben habe.
verstehe ich nich, ganz ohne Java-Code kann man die Aufgabe in Java nicht lösen


> Ist JFreeChart eine gute Lösung oder soll ich eine andere Chart variante wählen??
JFreeChart ist schon ok, wollte dazu nicht das Thema wechseln, ich meinte hängt davon ab wie das Objekt im Programm verwendet wird, 'ob da schon ein Objekt vor dem Parsen des XML besteht oder erst später' usw.,
pauschale Fragen zu getter und setter machen da auch keinen Unterschied,
alles muss sinnvoll programmiert werden, nicht mehr und nicht weniger

-----

hier ein kleines Testprogramm mit starken Vereinfachungen, die XML-Datei ist zu einem einfachen String verkümmert, statt Chart ein Dummy-Objekt

meine obigen Schritte gelten mehr oder weniger genauso, die Ursprungsdatei muss irgendwie verarbeitet werden so dass die Informationen vorliegen,
wie genau das bei deinem XML zu machen ist habe ich überhaupt noch nicht thematisiert, da gibt es 10 verschiede Parser,
da gibt es Suche nach Nodes oder alle per Schleife durchlaufen, such dir irgendwas aus, ganz egal, die Informationen müssen her,

und danach ist die Frage was mit den Informationen gemacht werden, hier werden nur Klassenattribute gesetzt, das kann schon ein guter Zwischenschritt sein (deine getter/setter-Frage?),
irgendwo irgendwann müssen dann in einem JFreeChart-Objekt komplizierte Konfigurations-Methoden aufgerufen werden,
aber das ist komplett unabhängig davon, WOHER die Information dafür stammt, ob direkt im Programm vorgegeben, ob aus einem XML, aus GUI-Einstellungen usw.
Java:
public class Test {
    public static void main(String[] args)  {
        String file = "a;b";
        String[] parts = file.split(";");

        Chart c = new Chart();
        c.chartEigenschaft1 = parts[0];
        c.chartEigenschaft2 = parts[1];

        // create Chart usw.
    }
}

class Chart {
    public String chartEigenschaft1;
    public String chartEigenschaft2;
}
 
Zuletzt bearbeitet von einem Moderator:
Vielen lieben Dank für deine Vorschläge, ich werde mal versuchen das umzusetzen.
Ich hoffe ich darf noch weiter fragen, wenn ich wieder auf Probleme stoße, danke nochmals.
 

Zurück
Oben