I need to have exactly one tickmark per datapoint.
I would love to give an array with the datapoints as parameter to the refreshTicksHorizontal in the NumberAxis (actually i work with symbolAxis which is a subclass) class which i have overwritten. Actually I did this, but I have absolutely know idea (after some hours of getting just nearly correct results) how to convert this double values into the pixel (or at least somehow mysteriously related to tickUnit) values i have to put into the currentTickValue variable in refreshTicksHorizontal.
I also tried – since the datapoints all have the same distance to its neighbours – to give
ratio = (datapoint[1] - datapoint[0]) / (Axis.UpperBound - datapoint[0])
as parameter and different other things. But i dont know the (pixel respectively Java2D)-value of the first datapoint so i could have my i-th currentTickValue as
ratio*i * (dataArea.getMaxX() - firstDataPointInJava2D)…
In my (wrong) solutions i always get slightly too big or too less tick mark distances. Do you know how to fix this or are there possibly entirely different approaches to the problem?
EDIT
To illustrate the problem here is a compiling minimalistic example:
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class Example {
public static void main(String[] args) {
double[] dataPoints = {1.249860779781E12, 1.249861186272E12, 1.249861592763E12, 1.249861999254E12,
1.249862405745E12};
String[] dataNames = {"Hades", "Hagen", "Herakles", "Hermes", "Horowitz"};
Shape shape = new Ellipse2D.Float(-2, -2, 4, 4);
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, true);
XYSeries[] lines = new XYSeries[5];
XYSeriesCollection dataset = new XYSeriesCollection();
for (int i = 0; i < 5; i++) {
lines[i] = new XYSeries(new Integer(i).toString());
lines[i].add(dataPoints[i], 0.05d);
lines[i].add(dataPoints[i], 0.95d);
dataset.addSeries(lines[i]);
renderer.setSeriesShape(i, shape);
renderer.setSeriesPaint(i, Color.black);
}
ValueAxis timeAxis = new DateAxis("");
NumberAxis yAxis = new NumberAxis("");
yAxis.setVisible(false);
yAxis.setTickMarksVisible(false);
yAxis.setRange(0.0d, 1.0d);
SymbolAxis labelAxis = new SymbolAxis("", dataNames);
labelAxis.setVerticalTickLabels(true);
XYPlot plot = new XYPlot(dataset, timeAxis, yAxis, renderer);
plot.setDomainAxis(1, labelAxis);
plot.setDomainAxisLocation(1, AxisLocation.TOP_OR_LEFT);
JFreeChart chart = new JFreeChart("", plot);
chart.removeLegend();
ChartPanel panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(800, 300));
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JScrollPane scroller = new JScrollPane(panel);
frame.add(scroller);
frame.pack();
frame.setVisible(true);
}
}
The result looks like this:

So far so good. The PROBLEM is, i want the names (Horowitz and so on) exactly over the lines. Can anyone help?
As a purely empirical measure, they line up perfectly using either
or
You may be able to generalize this as a function of your dataset.