Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
JFreeChart: nur jeden n-ten Wert auf der X-Achse anzeigen
Ich erzeuge mit JFreeChart einen Balken Chart. Dabei gibt es u.U. sehr viele Balken (Kategorien). Standardmäßig wird wird für jeden Balken ein Label unter der x-Achse gesetzt, was dann zur Foge hat, dass die Beschriftungen ineinanderlaufen und nicht mehr lesbar sind.
Wie erreiche ich, dass nur für jeden n-ten Balken eine Beschriftung gesetzt wird?
die Beschriftungen gibst du doch selber, modifiziere deinen Code zur Initialisierung des DataSets,
wobei gleiche Identifer, also String null oder "" oder " " glaube ich nicht so toll sind, ich hatte mir dafür einmal extra eine neue Klasse angelegt, vielleicht geht auch new String(" "); ?
wenn du dahingehend was machst und Probleme hast, dann sag Bescheid, am besten mit Beispielprogramm
oder meinst du wirklich Kategorien statt einzelner Werte? ein Beispielprogramm würde alles eindeutig erklären
"String.valueOf(i)" ist also mein "columnKey" und dieser wird (leider) als x-Achenbeschriftung angezeigt.
Kann ich irgendwie den columnKey und die x-Achenbeschriftung getrennt angeben?
(String.valueOf(i) ist die "Nummer" des aktuellen Arrayfeldes, später soll das mal ein Datumswert sein, aber zum testen geht das so)
Es ist ein Balkendiagramm das Werte einer täglich stattfindenden Aktion darstellen soll, also ein Balken pro Tag. Bei einem darzustellenden Zeitfenster von ein paar Tagen ist die Beschriftung jedes Balkens o.k., wenn aber ein ganzes Jahr dargestellt werden soll, ist die x-Achensbeschriftung nur noch ein Batzen in sich verschlungener Schrift. Dann sollte z.B. nur jeder 10. Balken beschriftet werden
hier ChartJava
gibt es Beispiel-Klassen für alle Charts,
wäre schön wenn du dir eine aussuchst, mit Schleife viele Dummy-Daten einfügst und das ganze dann postest,
damit ich es auch ausführen und das Problem sehen kann
ich habe selber sowohl mit allgemeinen Kategorien als auch mit Einzelwerten viel experimentiert,
es lohnt sich also wenn mir das ganze verständlich machen würdest
Ich habe "Bar Chart Demo 3" aus Deinem Link jetzt so verändert, dass das dataSet aus einem Array mit 100 Felden (das könnten in echt dann auch ein paar hundert werden) erzeugt wird.
Java:
//package org.jfree.chart.demo;
import java.awt.Color;
import java.awt.Paint;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.ui.TextAnchor;
/**
* A bar chart that uses a custom renderer to display different colors within a series.
* No legend is displayed because there is only one series but the colors are not consistent.
*
*/
public class BarChartDemo3 extends ApplicationFrame {
/**
* A custom renderer that returns a different color for each item in a single series.
*/
class CustomRenderer extends BarRenderer {
/** The colors. */
private Paint[] colors;
/**
* Creates a new renderer.
*
* @param colors the colors.
*/
public CustomRenderer(final Paint[] colors) {
this.colors = colors;
}
/**
* Returns the paint for an item. Overrides the default behaviour inherited from
* AbstractSeriesRenderer.
*
* @param row the series.
* @param column the category.
*
* @return The item color.
*/
public Paint getItemPaint(final int row, final int column) {
return this.colors[column % this.colors.length];
}
}
/**
* Creates a new demo.
*
* @param title the frame title.
*/
int[] myArray = new int[365];
public BarChartDemo3(final String title) {
super(title);
fillArray();
final CategoryDataset dataset = createDataset();
final JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
setContentPane(chartPanel);
}
private void fillArray() {
for (int i = 0; i < 365; i++) {
myArray[i] = (int) Math.round(Math.random() * 100);
}
}
/**
* Creates a sample dataset.
*
* @return a sample dataset.
*/
private CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
int[] myArray = new int[100];
for (int i = 0; i < 100; i++) {
myArray[i] = (int) Math.round(Math.random() * 100);
}
for (int i = 0; i < myArray.length; i++) {
dataset.addValue((myArray[i] / 1000000f), "", String.valueOf(i));
}
return dataset;
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
*
* @return a sample chart.
*/
private JFreeChart createChart(final CategoryDataset dataset) {
final JFreeChart chart = ChartFactory.createBarChart(
"Bar Chart Demo 3", // chart title
"Date", // domain axis label
"Value", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // the plot orientation
false, // include legend
true,
false);
chart.setBackgroundPaint(Color.lightGray);
// get a reference to the plot for further customisation...
final CategoryPlot plot = chart.getCategoryPlot();
plot.setNoDataMessage("NO DATA!");
// change the margin at the top of the range axis...
final ValueAxis rangeAxis = plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
rangeAxis.setLowerMargin(0.15);
rangeAxis.setUpperMargin(0.15);
return chart;
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(final String[] args) {
final BarChartDemo3 demo = new BarChartDemo3("Bar Chart Demo 3");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
Man sieht wie die Beschriftung der x-Achse unleserlich ineinander läuft. Das könnte man verhindern in dem man nur jeden n-ten (vielleicht 10-100-ten) Balken beschriftet. Und genau das bekomme ich nicht hin...
for (int i = 0; i < myArray.length; i++) {
String id = "";
if (i % 10 == 0) id = String.valueOf(i);
dataset.addValue((myArray[i] / 1000000f), "", id);
}
einfach die id überwiegend auf "" stellen,
leider gefällt JFreeChart das nicht bzw. macht duchaus auch Sinn, jeder Value ist durch seinen Identifer bestimmt,
mehrmals "" ist immer derselbe Eintrag,
ich habe mir dafür eine Extra-Klasse geschrieben, die trotz gleichen Inhalt bei compare nicht 0 zurückgibt,
intern wird noch eine eindeutige nummer vergeben und nach dieser nachrangig sortiert,
damit die compareTo-Rückgabe nicht völlig willkürlich ist, vielleicht unnötig
Java:
class IdentiferWrapper
implements Comparable<IdentiferWrapper>
{
private static int count;
private int number;
private Comparable identifer;
public IdentiferWrapper(Comparable identifer)
{
this.identifer = identifer;
this.number = count++;
}
public String toString()
{
return this.identifer.toString();
}
public int compareTo(IdentiferWrapper o)
{
if (this == o)
{
return 0;
}
int c = this.identifer.compareTo(o.identifer);
if (c == 0)
{
return this.number - o.number;
}
return c;
}
}
dann new IdentiferWrapper(id) statt id einfügen
------
Problem könnte noch sein, dass selbst die wenigen Labels nur als .. dargestellt werden,
das hier müsste dagegen helfen: