TickMarks in CategoryAxis?
TickMarks in CategoryAxis?
Hi,
why can i not draw TickMarks in a Category Axis? A Value or Number Axis can do and a Category Axis not?
why can i not draw TickMarks in a Category Axis? A Value or Number Axis can do and a Category Axis not?
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
The code to draw the tick marks hasn't been added to the CategoryAxis class yet. The implementation will need an extra flag to determine whether the tick marks are placed in the center of each category, or used to mark the boundary between two categories. It is on the to-do list (but has been for a long time, it isn't near the top of my list).
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


I've today developed a solution by myself. I added a method to draw TickMarks in CategoryAxis Class. The Marks are drawn at the position of the GridLines.
But now i've seen another problem. For example in a CategoryDataset with one series an a Bar3D Renderer. The first category is centered with the gridline, the second category is more to left 1Pixel (not centered) and many many categories again, the gridline and the Bar are completely wrong (xxx Pixels)
But now i've seen another problem. For example in a CategoryDataset with one series an a Bar3D Renderer. The first category is centered with the gridline, the second category is more to left 1Pixel (not centered) and many many categories again, the gridline and the Bar are completely wrong (xxx Pixels)
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
With the 3D renderer, you must also use the 3D axis...it is all an ugly hack. The 3D "effect" adds nothing to the information that your chart conveys - I recommend just using a 2D bar chart.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


OK now i've tried with 3D Axis and it works fine. But the GridLines are still drawn wrong. Now I've used the same method to recalculate coordinates as in 3D Axis and overwrite the drawDomainGridlines etc. methods, this works well. But is there not a standard solution?
I'm using CategoryAxis3D, BarRenderer3D and CategoryPlot, why are the Gridlines in standard not painted correct? Or is the fault on my side?
I'm using CategoryAxis3D, BarRenderer3D and CategoryPlot, why are the Gridlines in standard not painted correct? Or is the fault on my side?
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
You've found a bug. I've updated the CategoryAxis3D class and committed the change to CVS for the next release (0.9.21).
The change is to add this method:
The change is to add this method:
Code: Select all
/**
* Returns the Java 2D coordinate for a category.
*
* @param anchor the anchor point.
* @param category the category index.
* @param categoryCount the category count.
* @param area the data area.
* @param edge the location of the axis.
*
* @return the coordinate.
*/
public double getCategoryJava2DCoordinate(CategoryAnchor anchor,
int category,
int categoryCount,
Rectangle2D area,
RectangleEdge edge) {
double result = 0.0;
Rectangle2D adjustedArea = area;
CategoryPlot plot = (CategoryPlot) getPlot();
CategoryItemRenderer renderer = plot.getRenderer();
if (renderer instanceof Effect3D) {
Effect3D e3D = (Effect3D) renderer;
double adjustedX = area.getMinX();
double adjustedY = area.getMinY();
double adjustedW = area.getWidth() - e3D.getXOffset();
double adjustedH = area.getHeight() - e3D.getYOffset();
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.BOTTOM) {
adjustedY += e3D.getYOffset();
}
else if (edge == RectangleEdge.RIGHT || edge == RectangleEdge.TOP) {
adjustedX += e3D.getXOffset();
}
adjustedArea = new Rectangle2D.Double(
adjustedX, adjustedY, adjustedW, adjustedH
);
}
if (anchor == CategoryAnchor.START) {
result = getCategoryStart(category, categoryCount, adjustedArea, edge);
}
else if (anchor == CategoryAnchor.MIDDLE) {
result = getCategoryMiddle(category, categoryCount, adjustedArea, edge);
}
else if (anchor == CategoryAnchor.END) {
result = getCategoryEnd(category, categoryCount, adjustedArea, edge);
}
return result;
}
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


need to add tick marks for the category axis
Tobi,
I am using a regular bar chart and want to display the tick marks on the category axis...aligned to the center... Can I see the workaround code you did for this... till the cvs release comes through
thanks
I am using a regular bar chart and want to display the tick marks on the category axis...aligned to the center... Can I see the workaround code you did for this... till the cvs release comes through
thanks
Hi,
i have created a new Class extended from CategoryAxis and added these modified methods, works in 2D or 3D mode:
Now you have to set TickMarks visible like this:
YourAxis.setTickMarksVisible(true);
Hope this helps you?
Greetings,
Tobi
i have created a new Class extended from CategoryAxis and added these modified methods, works in 2D or 3D mode:
Code: Select all
/**
* Draws the axis on a Java 2D graphics device (such as the screen or a printer).
*
* @param g2 the graphics device (<code>null</code> not permitted).
* @param cursor the cursor location.
* @param plotArea the area within which the axis should be drawn (<code>null</code> not
* permitted).
* @param dataArea the area within which the plot is being drawn (<code>null</code> not
* permitted).
* @param edge the location of the axis (<code>null</code> not permitted).
* @param plotState collects information about the plot (<code>null</code> permitted).
*
* @return the axis state (never <code>null</code>).
*/
public AxisState draw(Graphics2D g2,
double cursor,
Rectangle2D plotArea,
Rectangle2D dataArea,
RectangleEdge edge,
PlotRenderingInfo plotState) {
AxisState state = new AxisState(cursor);
// if the axis is not visible, don't draw it...
if (!isVisible()) {
return new AxisState(cursor);
}
CategoryPlot plot = (CategoryPlot) getPlot();
Rectangle2D adjustedDataArea = new Rectangle2D.Double();
if (plot.getRenderer() instanceof Effect3D) {
Effect3D e3D = (Effect3D) plot.getRenderer();
double adjustedX = dataArea.getMinX();
double adjustedY = dataArea.getMinY();
double adjustedW = dataArea.getWidth() - e3D.getXOffset();
double adjustedH = dataArea.getHeight() - e3D.getYOffset();
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.BOTTOM) {
adjustedY += e3D.getYOffset();
}
else if (edge == RectangleEdge.RIGHT || edge == RectangleEdge.TOP) {
adjustedX += e3D.getXOffset();
}
adjustedDataArea.setRect(adjustedX, adjustedY, adjustedW, adjustedH);
}
else {
adjustedDataArea.setRect(dataArea);
}
if (isAxisLineVisible()) {
drawAxisLine(g2, cursor, adjustedDataArea, edge);
}
// draw the category labels and axis label
state = drawTickMarks(g2, cursor, plotArea, adjustedDataArea, edge);
state = drawCategoryLabels(g2, plotArea, adjustedDataArea, edge, state, plotState);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
/**
* Draws the axis line, tick marks and tick mark labels.
*
* @param g2 the graphics device.
* @param cursor the cursor.
* @param plotArea the plot area.
* @param dataArea the data area.
* @param edge the edge that the axis is aligned with.
*
* @return The width or height used to draw the axis.
*/
protected AxisState drawTickMarks(Graphics2D g2,
double cursor,
Rectangle2D plotArea,
Rectangle2D dataArea,
RectangleEdge edge) {
AxisState state = new AxisState(cursor);
double ol = getTickMarkOutsideLength();
double il = getTickMarkInsideLength();
List ticks = refreshTicks(g2, state, plotArea, dataArea, edge);
state.setTicks(ticks);
Iterator iterator = ticks.iterator();
int cnt = 0;
while (iterator.hasNext()) {
CategoryTick tick = (CategoryTick) iterator.next();
if (isTickMarksVisible()) {
float xx = (float) translateValueToJava2D(cnt, dataArea, edge);
Line2D mark = null;
g2.setStroke(getTickMarkStroke());
g2.setPaint(getTickMarkPaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor - ol, xx, cursor + il, xx);
}
else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor + ol, xx, cursor - il, xx);
}
else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double(xx, cursor - ol, xx, cursor + il);
}
else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double(xx, cursor + ol, xx, cursor - il);
}
g2.draw(mark);
}
cnt++;
}
return state;
}
public double translateValueToJava2D(int count,
Rectangle2D area,
RectangleEdge edge) {
CategoryPlot plot = (CategoryPlot)getPlot();
CategoryAnchor anchor = plot.getDomainGridlinePosition();
RectangleEdge domainAxisEdge = edge;//plot.getDomainAxisEdge();
CategoryDataset data = plot.getDataset();
if (data != null) {
CategoryAxis axis = plot.getDomainAxis();
if (axis != null) {
int columnCount = data.getColumnCount();
return axis.getCategoryJava2DCoordinate(
anchor, count, columnCount, area, domainAxisEdge
);
}
}
return 0.0d;
}
YourAxis.setTickMarksVisible(true);
Hope this helps you?
Greetings,
Tobi
TickMarks in CategoryAxis?
tobi,
thank you for the code.... however I did wat u suggested and I still do not see the tick marks
public class extendedCategoryAxis extends CategoryAxis{
................added all the 3 methods you suggested
}
Compiled the class and then used the code in my calling servlet
In my main code:
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setRange(rangeAxis.getLowerBound(), rangeAxis.getUpperBound() );
extendedCategoryAxis cAxis = (extendedCategoryAxis)plot.getDomainAxis();
cAxis.setTickMarksVisible(true);
But it still does not work?? This is a regular bar chart not 3D.....Any suggestions...
thank you for the code.... however I did wat u suggested and I still do not see the tick marks
public class extendedCategoryAxis extends CategoryAxis{
................added all the 3 methods you suggested
}
Compiled the class and then used the code in my calling servlet
In my main code:
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setRange(rangeAxis.getLowerBound(), rangeAxis.getUpperBound() );
extendedCategoryAxis cAxis = (extendedCategoryAxis)plot.getDomainAxis();
cAxis.setTickMarksVisible(true);
But it still does not work?? This is a regular bar chart not 3D.....Any suggestions...
Maybe try plot.setDomainAxis(cAxis) after doing all this.
And/or:
cAxis.setTickMarkOutsideLength(float length);
cAxis.setTickMarkPaint(axisPaint);
to set a real paint!
If it doesn't work, try to find out if your application goes into the modified method "draw" of the new class extendedCategoryAxis. If not you have to find the fault, why not.
If there are no compiling errors, the new class should work fine, in 2D AND 3D!
And/or:
cAxis.setTickMarkOutsideLength(float length);
cAxis.setTickMarkPaint(axisPaint);
to set a real paint!
If it doesn't work, try to find out if your application goes into the modified method "draw" of the new class extendedCategoryAxis. If not you have to find the fault, why not.
If there are no compiling errors, the new class should work fine, in 2D AND 3D!
CategoryAxis Ticks display
Tobi,
I had to do the following and it worked
tx so much for your help
MyCategoryAxis ca = new MyCategoryAxis();
ca.setTickMarksVisible(true);
ca.setTickMarkOutsideLength(2.0f);
ca.setTickMarkPaint(Color.black);
plot.setDomainAxis(ca);
I had to do the following and it worked
tx so much for your help
MyCategoryAxis ca = new MyCategoryAxis();
ca.setTickMarksVisible(true);
ca.setTickMarkOutsideLength(2.0f);
ca.setTickMarkPaint(Color.black);
plot.setDomainAxis(ca);