# jfreechart: Barplot, auf ein neues :)



## schlumsch (17. Feb 2009)

Hallo ...und da bin ich wieder 
...Ich mach`da mal ein neues Thema
2 bzw 3 Fragen zum Thema JFreechart und Barplots hab ich da noch:

1.) Kann man eigentlich in einem Barplot die Breite der einzelnen Bars festlegen,
ohne die Maße des gesammten Diagrammes anzufassen? 

2.) Man kann für ein ganzes Diahgramm einen Tooltip - also ein Infofenster bei mouseover festlegen. Kann man dies auch für einzelne Bars tun, derart das z.B die beschriftung der y-Achse der jeweilichen Bar ausgegeben wird, wenn der benutzer über die einzelne Bar mit der Maus fährt? Die Erweiterung wäre dann, ein onklick zu erfassen, wenn der Nutzer auf eine Bar klickt... Hat da jemand Ahnung???

Danke euch, lg schlumsch


----------



## SlaterB (17. Feb 2009)

zu 1. benutze ich
http://www.jfree.org/jfreechart/api...y/BarRenderer.html#setMaximumBarWidth(double)

mehr habe ich auch gerade in der API nicht gesehen,
vielleicht müsste man 
http://www.jfree.org/jfreechart/api....renderer.category.CategoryItemRendererState)
überschreiben,

zu 2. gesehen:
http://www.jfree.org/jfreechart/api....jfree.chart.labels.CategoryToolTipGenerator)


----------



## schlumsch (17. Feb 2009)

Ja, danke erstmal.
zu 1. noch eine Frage: die methode SetMaximum... gibt es bei mir
weder am Chart noch am Renderer. Wenn ich das richtig sehe, muss ich
dazu dem Barrenderer das Property selber noch implemenmtieren. Den Renderer habe ich gefunden und den entsprechenden Code hab ich auch... behaupte ich jetzt zuminjdest mal, aber was mache ich, wenn ich die entsprechenden Zeilen hinzugefügt hab? Sprich- das ganze müsste ich ja nun auch noch als lib exportieren, um es in meinem JBoss zum laufen zu bekommen, right? Was genau exportiere ich da wohin??


----------



## SlaterB (17. Feb 2009)

was du genau an Renderern vorliegen hast, kann ich nicht ahnen,
vielleicht musst du nur auf BarRenderer casten, 
Code posten

ohne JFreeChart-Library wird dein JBoss-Server bisher kaum Charts erzeugt haben,
und neue Klassen zu schreiben schlage ich einerfalls nur als letzte Notlösung vor, sollte andererseits aber kein Problem sein, da dein Programm doch eh aus mindestens schon einer eigener Klasse besteht oder? 

warum du ne ganz lib exportieren willst, verstehe nich noch nicht ganz,
irgendwo muss aber ein lib-Verzeichnis sein, allein schon für JFreeChart, 
oder Classpath?


----------



## schlumsch (17. Feb 2009)

Hallo,

also zuerst mal stimme ich dir absolut zu... Hansa wird Meister! 

Dann habe ich auch mitbekommen, das mein vorheriges Posting nicht so wirklich sinnvoll ist. Ich habe in meine BarRenderer-Klasse geschaut und finde dort schon das Property setMax..., allerdings weiss ich nicht, wie ich dies in meinem chart einfüge. Hier mal ein Codeschnipsel


		JFreeChart chart = ChartFactory
				.createBarChart(
						"", //$NON-NLS-1$
						msg.getString("TourBean.COSTBARPLOTXAXIS"), msg.getString("TourBean.COSTBARPLOTYAXIS"), dataset, PlotOrientation.HORIZONTAL, false, //$NON-NLS-1$ //$NON-NLS-2$
						true, false);

		chart.setBackgroundPaint(Color.decode(msg
				.getString("TourBean.COSTBARPLOTBGCOLOR")));
		chart.getTitle().setPaint(
				Color.decode(msg.getString("TourBean.COSTBARPLOTTITLECOLOR")));


		CategoryPlot p = chart.getCategoryPlot();
		CategoryItemRenderer render = p.getRenderer();

		render.setBaseItemLabelGenerator(new CustomItemLabelGenerator());


----------



## SlaterB (17. Feb 2009)

renderer ist entweder schon ein BarRenderer (testen zu casten),
ansonsten

BarRenderer renderer = new BarRenderer();
                plot.setRenderer(renderer);


----------



## schlumsch (19. Feb 2009)

Tsja, also irgendwas habe ich an der ganzen Geschichte noch nicht verstanden. Das Casten auf BarRenderer funktioniert, auch kann ich setMax... mit einem Wert aufrufen, allerdings passiert daraufhin erstmal garnix... jedenfalls nichts neues... 
Egal welchen Wert ich in setMax... einbaue (0.3, 2, 80 hab ich mal probiert)

Ich gehe davon aus, dass in meinem Restlichen Code orgendwo der Fehler steckzt, kannst du dir das mal bitte anschauen, wäre ich dir wirklich dankbar...

lg & thx im voraus
schlumsch

JFreeChart chart = ChartFactory
				.createBarChart(....);

CategoryPlot p = chart.getCategoryPlot();
		CategoryItemRenderer renderer = p.getRenderer();


		BarRenderer render = (BarRenderer) renderer;
		render.setMaximumBarWidth(80);
		chart.getCategoryPlot().setRenderer(render);
		render.setBaseItemLabelGenerator(new CustomItemLabelGenerator());





		DecimalFormat labelFormatter = new DecimalFormat("##,###.##");
        labelFormatter.setNegativePrefix("(");
        labelFormatter.setNegativeSuffix(")");
        chart.getCategoryPlot().getRenderer().setItemLabelGenerator(
            new StandardCategoryItemLabelGenerator("{2}", labelFormatter)
        );
        chart.getCategoryPlot().getRenderer().setItemLabelsVisible(true);





		// ItemLabel Position
		render.setBasePositiveItemLabelPosition(new ItemLabelPosition(
				ItemLabelAnchor.CENTER, TextAnchor.CENTER));
		// Schriftgrößen
		int xxx = Integer.parseInt(msg
				.getString("TourBean.COSTBARPLOTITEMLABELFONTSIZE"));
		render.setBaseItemLabelFont(new Font(msg
				.getString("TourBean.COSTBARPLOTITEMLABELFONTNAME"),
				Font.PLAIN, xxx));
		render.setBaseItemLabelsVisible(true);

		// Farbe Balken
		render.setSeriesPaint(0, Color.decode(msg
				.getString("TourBean.COSTBARPLOTBARCOLOR")));
		p.setBackgroundPaint(Color.decode(msg
				.getString("TourBean.COSTBARPLOTBGCOLORDIAGRAM")));
		p.setRangeGridlinePaint(Color.decode(msg
				.getString("TourBean.COSTBARPLOTBARCOLOR")));
		// p.setBackgroundPaint(Color.lightGray);
		// p.setRangeGridlinePaint(Color.orange);

		int uID = getUserId(this.userName);
		String costPlotSaveTo = msg
				.getString("TourBean.COSTBARPLOTSAVEIMAGEURL1")
				+ uID + msg.getString("TourBean.COSTBARPLOTSAVEIMAGEURL2");
		String costPlotloadFrom = msg
				.getString("TourBean.COSTBARPLOTVIEWIMAGEURL1")
				+ uID + msg.getString("TourBean.COSTBARPLOTVIEWIMAGEURL2");
		try {
			ChartUtilities.saveChartAsJPEG(new File(costPlotSaveTo), chart,
					320, //$NON-NLS-1$
					220);
			url = costPlotloadFrom; //$NON-NLS-1$
		} catch (IOException e) {
			System.err.println(msg
					.getString("TourBean.COSTBARPLOTERRORMESSAGE")); //$NON-NLS-1$
		}
		return url;
	}


----------



## SlaterB (19. Feb 2009)

ein vollständiges Beispiel (in [ code] [/ code] Tags!) wäre hilfreich, mit Testdaten 

und irrelevanter Quark wie 
> String costPlotSaveTo = msg .getString("TourBean.COSTBARPLOTSAVEIMAGEURL1")
> + uID + msg.getString("TourBean.COSTBARPLOTSAVEIMAGEURL2") ;
hat bestimmt nix mit dem Problem zu tun, besser testweise löschen

-------

grundsätzlich solltest du von setMaximumBarWidth() nicht zu viel erwarten,
es kann weder die Bars grün färben noch ihre Durchschnittsgröße setzen, sondern nur genau das was der Name aussagt,
brauchst du das überhaupt? deine Ursprungsfrage klang ja etwas allgemeiner


----------



## schlumsch (19. Feb 2009)

Jo, also was ich brauche/habe ist folgendes:

Mein Diagramm hat eine Höhe von sagen wir 300px und das soll auch so bleiben. Derzeit sind alle dargestellten Bars sagen wir 20px "dick"... die sollen nun aber nur 10px dick sein und der plot immernoch 300px hoch, thats it.

Soll ich mal die Methode soweit umbasteln, dass es zu testen ist, oder ist setMax... doch nicht die richtige Lösung für mein Anliegen? lg


----------



## SlaterB (19. Feb 2009)

```
public class BarChartDemo3
    extends ApplicationFrame
{

    public BarChartDemo3(final String title)
    {
        super(title);

        double[][] data =  {{4.0, 12.0, -2.0, 3.0, 6.0}};
        CategoryDataset dataset = DatasetUtilities.createCategoryDataset("Series ", "C", data);
        JFreeChart chart = ChartFactory.createBarChart("X", "C", "V", dataset, PlotOrientation.VERTICAL, true, true, false);
        CategoryPlot plot = chart.getCategoryPlot();
        BarRenderer b = (BarRenderer)plot.getRenderer();
        b.setMaximumBarWidth(0.04);

        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(300, 300));
        setContentPane(chartPanel);
    }

    public static void main(final String[] args)
    {
        BarChartDemo3 demo = new BarChartDemo3("Bar Chart Demo 3");
        demo.pack();
        demo.setVisible(true);
    }
}
```
schau dir den Unterschied an, mit und ohne setMaximumBarWidth,
der übergebene Wert bedeutet hier 4% der Chart-Breite


----------



## schlumsch (24. Feb 2009)

Jau cooles Ding! Bin nun endlich dazu gekommen, das ganze zu probieren und es funktioniert wunderbar. Ich schätze mal, ich habe nur bei der Übergabe des Parameters einen Fehler gemacht


----------



## schlumsch (24. Feb 2009)

...aber etwas fällt mir da doch noch ein, die Frage hatte ich glaube ich schon einmal im Forum gepostet, vielleicht kannst du mir da helfen. Ich speichere derzeit die Bilder physisch auf HD und lasse sie dann in meinem xhtml in einem Grid ausgeben. kannst du mir sagen, wie ich sen Speichervorgang umgehen kann und die Plots dennoch in den Grids anzeigen lassen kann?


----------



## SlaterB (24. Feb 2009)

weiß nicht genau, was du meinst, was ein Grid ist usw., dazu kann ich wohl nix sagen,

wenn du ChartUtilities.saveChartAsJPEG() umbiegen willst, dass es dir ein Image-Objekt im Speicher erstellt, oder ein byte[] liefert,
dann kopiere dir den Quelltext der Klasse und tausche FileOutputStream durch ByteArrayOutputStream oder was auch immer,
bei der Anzeige durch ChartPanel kann man auch tricksen, ein Graphics-Objekt eines Bildes übergeben oder so


----------



## schlumsch (24. Feb 2009)

Ja das ist mal einen Versuch wert. Das von mir angesprochene Grid ist im Endeffekt nichts weiter als ein html-table bzw. eben eine col in diesem, sprich ich will tatsächlich das Bild im Speicher halten und eben in die "Struktur der Page", nicht auf ein extra Panel ausgeben. Ich versuche mal deinen Ansatz, bin mir sicher das da was schiefgehen wird :9 ...da kenn ich mich doch...


----------



## schlumsch (24. Feb 2009)

Hmmm, najamalso der Umbau klappt soweit, allerdings weiss ich nicht, wie ich den Plot nun anzeigen soll. Sprich bislang hab ich einfach die url des Bildes ausgegeben :  

<h:graphicImage value="#{draw.printCostBarPlot}" title="x" width="320px" height="220px"/>

wobei mir eben die methode printCostBarPlot die url des Bildes geliefert hat


----------



## SlaterB (24. Feb 2009)

ich erstelle PDF-Dateien mit XSL und habe darin ähnliches:
<fo:external-graphic src="url({chartFilepath})" width="{chartWidth}" height="{chartHeight}"/>

wie man sehen kann, auch über Zwischenspeichern auf der Festplatte, ich kann da also nicht weiterhelfen


----------



## schlumsch (24. Feb 2009)

Hmkay, dann ist dies die Stelle für einen neuen Thread  Danke dir aber für deine Hilfe!
lg


----------

