Search code examples
javalabelcustomizationjfreechartpercentage

Custom percentage thresholds on y-axis with uneven spacing


My problem: Using , I need to display unevenly spaced percentage thresholds on the y-axis. For example, the only labels on my y-axis should be the thresholds as follows; all other ordinates should be blank:

-
93%
85%
78%
72%
66%
-
50%
-
-
-
-
-

I am currently using this code snippet for percentages display, but this will just create an evenly spaced percentage axis:

    CategoryPlot plot = (CategoryPlot) chart.getPlot();

    NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
    DecimalFormat pctFormat = new DecimalFormat("#.0%");
    rangeAxis.setNumberFormatOverride(pctFormat);

Any help would be appreciated!


Solution

  • This is a somewhat hacked-up answer, and i will upvote any answer that gets the same result in a good way. But it works - here is what i did.

    First, i created a list of the double values i wanted to be used:

    public static List<Double> m_lPercentageValuesForY = Arrays.asList(0.1,0.2,0.3,0.4,0.5,0.58,0.66,0.70,0.74,0.78,0.82,0.95,1.0);
    

    Then i overwrite the refreshTicks method in NumberAxis to first set all default ticks to Ticktype.MINOR, and then add and create my custom ticks with Ticktype.MAJOR:

        NumberAxis axisLeft = new NumberAxis(plot.getRangeAxis().getLabel()) {
            @Override
            public List refreshTicks(
                    Graphics2D g2, 
                    AxisState state,
                    Rectangle2D dataArea, 
                    RectangleEdge edge) {
    
                List defaultTicks = super.refreshTicks(g2, state, dataArea, edge);
                List customTicks = new ArrayList();
    
                for (Object aTick : defaultTicks) {
                    NumberTick currenttick = (NumberTick) aTick;
    
                    customTicks.add(new NumberTick(
                            TickType.MINOR, 
                            currenttick.getValue(), 
                            "",  //empty
                            currenttick.getTextAnchor(), 
                            currenttick.getRotationAnchor(),
                            currenttick.getAngle()));
                }
                NumberTick aTick = (NumberTick) defaultTicks.get(0);
                for (double dTest : m_lPercentageValuesForY) {
                    customTicks.add(new NumberTick(
                            TickType.MAJOR, 
                            dTest, 
                            String.format("%.0f%%", dTest * 100), //only wanted values are set to major
                            aTick.getTextAnchor(), 
                            aTick.getRotationAnchor(),
                            aTick.getAngle()));
                }
                return customTicks;
            }
        };
        plot.setRangeAxis(axisLeft);