JFreeChart is a comprehensive free chart library for the Java platform that enables developers to create professional-quality charts for both client-side and server-side applications with export capabilities to multiple formats including PNG and JPEG.
—
Axis management for controlling coordinate systems, labels, tick marks, and value ranges. Axes define the coordinate space for plots and provide the visual framework for interpreting chart data through scales, labels, and grid lines.
Common functionality for all axis types including labels, tick marks, and visual appearance.
/**
* Abstract base class for all axis types
*/
public abstract class Axis implements Cloneable, Serializable {
// Visibility control
public boolean isVisible();
public void setVisible(boolean flag);
// Axis label
public String getLabel();
public void setLabel(String label);
public Font getLabelFont();
public void setLabelFont(Font font);
public Paint getLabelPaint();
public void setLabelPaint(Paint paint);
public RectangleInsets getLabelInsets();
public void setLabelInsets(RectangleInsets insets);
public double getLabelAngle();
public void setLabelAngle(double angle);
public AxisLabelLocation getLabelLocation();
public void setLabelLocation(AxisLabelLocation location);
// Axis line
public boolean isAxisLineVisible();
public void setAxisLineVisible(boolean visible);
public Stroke getAxisLineStroke();
public void setAxisLineStroke(Stroke stroke);
public Paint getAxisLinePaint();
public void setAxisLinePaint(Paint paint);
// Tick labels
public boolean isTickLabelsVisible();
public void setTickLabelsVisible(boolean flag);
public Font getTickLabelFont();
public void setTickLabelFont(Font font);
public Paint getTickLabelPaint();
public void setTickLabelPaint(Paint paint);
public RectangleInsets getTickLabelInsets();
public void setTickLabelInsets(RectangleInsets insets);
// Tick marks
public boolean isTickMarksVisible();
public void setTickMarksVisible(boolean flag);
public float getTickMarkInsideLength();
public void setTickMarkInsideLength(float length);
public float getTickMarkOutsideLength();
public void setTickMarkOutsideLength(length);
public Stroke getTickMarkStroke();
public void setTickMarkStroke(Stroke stroke);
public Paint getTickMarkPaint();
public void setTickMarkPaint(Paint paint);
// Minor tick marks
public boolean isMinorTickMarksVisible();
public void setMinorTickMarksVisible(boolean flag);
public float getMinorTickMarkInsideLength();
public void setMinorTickMarkInsideLength(float length);
public float getMinorTickMarkOutsideLength();
public void setMinorTickMarkOutsideLength(float length);
// Fixed dimension
public double getFixedDimension();
public void setFixedDimension(double dimension);
// Change notification
public void addChangeListener(AxisChangeListener listener);
public void removeChangeListener(AxisChangeListener listener);
// Abstract methods
public abstract AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotRenderingInfo);
public abstract List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge);
}Base class for axes that display numeric values, providing range management and coordinate transformations.
/**
* Abstract base class for axes that display numeric values
*/
public abstract class ValueAxis extends Axis {
// Range management
public Range getRange();
public void setRange(Range range);
public void setRange(double lower, double upper);
public double getLowerBound();
public void setLowerBound(double min);
public double getUpperBound();
public void setUpperBound(double max);
// Auto-ranging
public boolean isAutoRange();
public void setAutoRange(boolean auto);
public boolean isAutoTickUnitSelection();
public void setAutoTickUnitSelection(boolean flag);
public double getAutoRangeMinimumSize();
public void setAutoRangeMinimumSize(double size);
public double getDefaultAutoRange();
public void setDefaultAutoRange(Range range);
// Axis orientation
public boolean isInverted();
public void setInverted(boolean inverted);
// Margins
public double getLowerMargin();
public void setLowerMargin(double margin);
public double getUpperMargin();
public void setUpperMargin(double margin);
// Arrows
public boolean isPositiveArrowVisible();
public void setPositiveArrowVisible(boolean visible);
public boolean isNegativeArrowVisible();
public void setNegativeArrowVisible(boolean visible);
public Shape getUpArrow();
public void setUpArrow(Shape arrow);
public Shape getDownArrow();
public void setDownArrow(Shape arrow);
public Shape getLeftArrow();
public void setLeftArrow(Shape arrow);
public Shape getRightArrow();
public void setRightArrow(Shape arrow);
// Coordinate transformation
public abstract double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge);
public abstract double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge);
// Range operations
public void centerRange(double value);
public void setRangeAboutValue(double value, double length);
public void resizeRange(double percent);
public void resizeRange(double percent, double anchorValue);
public void resizeRange2(double percent, double anchorValue);
public void zoomRange(double lowerPercent, double upperPercent);
public void pan(double percent);
// Tick units
public TickUnit getTickUnit();
public void setTickUnit(TickUnit unit);
public void setTickUnit(TickUnit unit, boolean notify, boolean turnOffAutoSelection);
}Axis for displaying numeric values with number formatting and auto-ranging capabilities.
/**
* Axis for displaying numeric values
*/
public class NumberAxis extends ValueAxis {
/**
* Creates a number axis with no label
*/
public NumberAxis();
/**
* Creates a number axis with a label
* @param label the axis label
*/
public NumberAxis(String label);
// Number formatting
public NumberFormat getNumberFormatOverride();
public void setNumberFormatOverride(NumberFormat formatter);
public RectangleInsets getTickLabelInsets();
public void setTickLabelInsets(RectangleInsets insets);
// Auto-range behavior
public boolean isAutoRangeIncludesZero();
public void setAutoRangeIncludesZero(boolean flag);
public boolean isAutoRangeStickyZero();
public void setAutoRangeStickyZero(boolean flag);
// Tick units
public TickUnitSource getStandardTickUnits();
public void setStandardTickUnits(TickUnitSource source);
public static TickUnitSource createIntegerTickUnits();
public static TickUnitSource createStandardTickUnits();
// Tick labels
public boolean isVerticalTickLabels();
public void setVerticalTickLabels(boolean flag);
// Range type
public RangeType getRangeType();
public void setRangeType(RangeType rangeType);
}
/**
* Logarithmic number axis
*/
public class LogAxis extends ValueAxis {
/**
* Creates a logarithmic axis with no label
*/
public LogAxis();
/**
* Creates a logarithmic axis with a label
* @param label the axis label
*/
public LogAxis(String label);
public double getBase();
public void setBase(double base);
public String getBaseSymbol();
public void setBaseSymbol(String symbol);
public boolean isBaseFormatter();
public void setBaseFormatter(boolean baseFormatter);
public NumberFormat getBaseFormat();
public void setBaseFormat(NumberFormat formatter);
public boolean isLogTickLabelsFlag();
public void setLogTickLabelsFlag(boolean flag);
public boolean isExpTickLabelsFlag();
public void setExpTickLabelsFlag(boolean flag);
public boolean isStrictValuesFlag();
public void setStrictValuesFlag(boolean flg);
public boolean getAllowNegativesFlag();
public void setAllowNegativesFlag(boolean flg);
}Usage Example:
import org.jfree.chart.axis.*;
import java.text.DecimalFormat;
// Create and customize number axis
NumberAxis yAxis = new NumberAxis("Revenue ($)");
yAxis.setRange(0, 1000000);
yAxis.setAutoRange(false);
yAxis.setAutoRangeIncludesZero(true);
// Custom number formatting
DecimalFormat formatter = new DecimalFormat("$#,##0");
yAxis.setNumberFormatOverride(formatter);
// Customize appearance
yAxis.setLabelFont(new Font("Arial", Font.BOLD, 14));
yAxis.setTickLabelFont(new Font("Arial", Font.PLAIN, 12));
yAxis.setLabelPaint(Color.BLUE);
yAxis.setTickLabelPaint(Color.BLACK);
// Set custom tick units
yAxis.setTickUnit(new NumberTickUnit(50000));
yAxis.setMinorTickMarksVisible(true);
// Apply to plot
plot.setRangeAxis(yAxis);
// Create logarithmic axis
LogAxis logAxis = new LogAxis("Log Scale");
logAxis.setBase(10);
logAxis.setStrictValuesFlag(false);
logAxis.setAllowNegativesFlag(false);
logAxis.setAutoRangeMinimumSize(1.0);
plot.setRangeAxis(logAxis);Axis for displaying date and time values with automatic date formatting and time zone support.
/**
* Axis for displaying date and time values
*/
public class DateAxis extends ValueAxis {
/**
* Creates a date axis with no label
*/
public DateAxis();
/**
* Creates a date axis with a label
* @param label the axis label
*/
public DateAxis(String label);
// Date range
public Date getMinimumDate();
public void setMinimumDate(Date date);
public Date getMaximumDate();
public void setMaximumDate(Date date);
public Range getDefaultAutoRange();
public void setDefaultAutoRange(Range range);
// Date formatting
public DateFormat getDateFormatOverride();
public void setDateFormatOverride(DateFormat formatter);
// Tick units
public DateTickUnit getTickUnit();
public void setTickUnit(DateTickUnit unit);
public DateTickMarkPosition getTickMarkPosition();
public void setTickMarkPosition(DateTickMarkPosition position);
// Time zone
public TimeZone getTimeZone();
public void setTimeZone(TimeZone zone);
// Timeline support
public Timeline getTimeline();
public void setTimeline(Timeline timeline);
// Date utility methods
public static Date calculateLowestVisibleTickValue(DateTickUnit unit, Date lowerBound, DateTickMarkPosition tickMarkPosition, TimeZone timeZone);
public static Date calculateHighestVisibleTickValue(DateTickUnit unit, Date upperBound, DateTickMarkPosition tickMarkPosition, TimeZone timeZone);
public static Date nextStandardDate(Date date, DateTickUnit unit);
public static Date previousStandardDate(Date date, DateTickUnit unit);
}
/**
* Date tick unit for controlling date axis tick spacing
*/
public class DateTickUnit extends TickUnit {
/**
* Creates a date tick unit
* @param unitType the date unit type (YEAR, MONTH, DAY, etc.)
* @param multiple the multiple of the unit type
*/
public DateTickUnit(DateTickUnitType unitType, int multiple);
/**
* Creates a date tick unit with custom formatting
* @param unitType the date unit type
* @param multiple the multiple of the unit type
* @param formatter the date formatter
*/
public DateTickUnit(DateTickUnitType unitType, int multiple, DateFormat formatter);
public DateTickUnitType getUnitType();
public int getMultiple();
public long getMillisecondCount();
public DateFormat getFormatter();
public String dateToString(Date date);
// Calendar field constants
public static final DateTickUnitType YEAR = new DateTickUnitType("YEAR", Calendar.YEAR);
public static final DateTickUnitType MONTH = new DateTickUnitType("MONTH", Calendar.MONTH);
public static final DateTickUnitType DAY = new DateTickUnitType("DAY", Calendar.DATE);
public static final DateTickUnitType HOUR = new DateTickUnitType("HOUR", Calendar.HOUR_OF_DAY);
public static final DateTickUnitType MINUTE = new DateTickUnitType("MINUTE", Calendar.MINUTE);
public static final DateTickUnitType SECOND = new DateTickUnitType("SECOND", Calendar.SECOND);
public static final DateTickUnitType MILLISECOND = new DateTickUnitType("MILLISECOND", Calendar.MILLISECOND);
}
/**
* Period axis for displaying time periods
*/
public class PeriodAxis extends ValueAxis {
/**
* Creates a period axis
* @param label the axis label
*/
public PeriodAxis(String label);
/**
* Creates a period axis with time zone
* @param label the axis label
* @param first the first period
* @param last the last period
*/
public PeriodAxis(String label, RegularTimePeriod first, RegularTimePeriod last);
public RegularTimePeriod getFirst();
public void setFirst(RegularTimePeriod first);
public RegularTimePeriod getLast();
public void setLast(RegularTimePeriod last);
public TimeZone getTimeZone();
public void setTimeZone(TimeZone timeZone);
public boolean isAutoRangeTimePeriodClass();
public void setAutoRangeTimePeriodClass(Class timePeriodClass);
public PeriodAxisLabelInfo[] getLabelInfo();
public void setLabelInfo(PeriodAxisLabelInfo[] info);
}Usage Example:
import org.jfree.chart.axis.*;
import org.jfree.data.time.*;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
// Create date axis
DateAxis timeAxis = new DateAxis("Time");
// Set date range
Calendar cal = Calendar.getInstance();
cal.set(2023, Calendar.JANUARY, 1);
Date startDate = cal.getTime();
cal.set(2023, Calendar.DECEMBER, 31);
Date endDate = cal.getTime();
timeAxis.setMinimumDate(startDate);
timeAxis.setMaximumDate(endDate);
// Custom date formatting
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM yyyy");
timeAxis.setDateFormatOverride(dateFormat);
// Set tick unit
timeAxis.setTickUnit(new DateTickUnit(DateTickUnitType.MONTH, 1));
timeAxis.setTickMarkPosition(DateTickMarkPosition.START);
// Time zone support
timeAxis.setTimeZone(TimeZone.getTimeZone("America/New_York"));
// Apply to plot
plot.setDomainAxis(timeAxis);
// Period axis example
PeriodAxis periodAxis = new PeriodAxis("Quarters");
periodAxis.setFirst(new Quarter(1, 2023));
periodAxis.setLast(new Quarter(4, 2024));
periodAxis.setTimeZone(TimeZone.getDefault());
// Configure period labels
PeriodAxisLabelInfo[] labelInfo = new PeriodAxisLabelInfo[2];
labelInfo[0] = new PeriodAxisLabelInfo(Quarter.class, new SimpleDateFormat("Q"));
labelInfo[1] = new PeriodAxisLabelInfo(Year.class, new SimpleDateFormat("yyyy"));
periodAxis.setLabelInfo(labelInfo);Axis for displaying categorical labels with support for label positioning and rotation.
/**
* Axis for displaying category labels
*/
public class CategoryAxis extends Axis {
/**
* Creates a category axis with no label
*/
public CategoryAxis();
/**
* Creates a category axis with a label
* @param label the axis label
*/
public CategoryAxis(String label);
// Margins
public double getLowerMargin();
public void setLowerMargin(double margin);
public double getUpperMargin();
public void setUpperMargin(double margin);
public double getCategoryMargin();
public void setCategoryMargin(double margin);
// Label display
public int getMaximumCategoryLabelLines();
public void setMaximumCategoryLabelLines(int lines);
public float getMaximumCategoryLabelWidthRatio();
public void setMaximumCategoryLabelWidthRatio(float ratio);
public int getCategoryLabelPositionOffset();
public void setCategoryLabelPositionOffset(int offset);
// Label positioning
public CategoryLabelPositions getCategoryLabelPositions();
public void setCategoryLabelPositions(CategoryLabelPositions positions);
public boolean isVerticalCategoryLabels();
public void setVerticalCategoryLabels(boolean flag);
// Coordinate calculations
public double getCategoryStart(int category, int categoryCount, Rectangle2D area, RectangleEdge edge);
public double getCategoryMiddle(int category, int categoryCount, Rectangle2D area, RectangleEdge edge);
public double getCategoryEnd(int category, int categoryCount, Rectangle2D area, RectangleEdge edge);
public double getCategorySeriesMiddle(int categoryIndex, int categoryCount, int seriesIndex, int seriesCount, double itemMargin, Rectangle2D area, RectangleEdge edge);
// Java2D coordinate conversion
public double categoryToJava2D(Comparable category, Rectangle2D area, RectangleEdge edge);
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge);
public Comparable java2DToCategory(double java2DValue, Rectangle2D area, RectangleEdge edge);
}
/**
* Sub-category axis for hierarchical categories
*/
public class SubCategoryAxis extends CategoryAxis {
/**
* Creates a sub-category axis
* @param label the axis label
*/
public SubCategoryAxis(String label);
public void addSubCategory(Comparable subcategory);
public List getSubCategories();
public Paint getSubLabelPaint();
public void setSubLabelPaint(Paint paint);
public Font getSubLabelFont();
public void setSubLabelFont(Font font);
}
/**
* Extended category axis with additional features
*/
public class ExtendedCategoryAxis extends CategoryAxis {
/**
* Creates an extended category axis
* @param label the axis label
*/
public ExtendedCategoryAxis(String label);
public Map getSubLabelFonts();
public void setSubLabelFont(Comparable category, Font font);
public Font getSubLabelFont(Comparable category);
public Map getSubLabelPaints();
public void setSubLabelPaint(Comparable category, Paint paint);
public Paint getSubLabelPaint(Comparable category);
}
/**
* Symbol axis for displaying symbol-based labels
*/
public class SymbolAxis extends NumberAxis {
/**
* Creates a symbol axis
* @param label the axis label
* @param sv the list of symbols
*/
public SymbolAxis(String label, String[] sv);
public String[] getSymbols();
public void setSymbols(String[] symbols);
public boolean isGridBandsVisible();
public void setGridBandsVisible(boolean flag);
public Paint getGridBandPaint();
public void setGridBandPaint(Paint paint);
public Paint getGridBandAlternatePaint();
public void setGridBandAlternatePaint(Paint paint);
}Usage Example:
import org.jfree.chart.axis.*;
// Create category axis
CategoryAxis categoryAxis = new CategoryAxis("Products");
// Configure margins
categoryAxis.setLowerMargin(0.02);
categoryAxis.setUpperMargin(0.02);
categoryAxis.setCategoryMargin(0.10);
// Configure label display
categoryAxis.setMaximumCategoryLabelLines(3);
categoryAxis.setMaximumCategoryLabelWidthRatio(0.8f);
// Configure label positioning for angled labels
CategoryLabelPositions positions = new CategoryLabelPositions(
new CategoryLabelPosition(RectangleAnchor.BOTTOM_LEFT, TextAnchor.BOTTOM_LEFT,
TextAnchor.BOTTOM_LEFT, -Math.PI / 4.0),
new CategoryLabelPosition(RectangleAnchor.TOP_LEFT, TextAnchor.TOP_LEFT,
TextAnchor.TOP_LEFT, -Math.PI / 4.0),
new CategoryLabelPosition(RectangleAnchor.BOTTOM_RIGHT, TextAnchor.BOTTOM_RIGHT,
TextAnchor.BOTTOM_RIGHT, Math.PI / 4.0),
new CategoryLabelPosition(RectangleAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT,
TextAnchor.TOP_RIGHT, Math.PI / 4.0)
);
categoryAxis.setCategoryLabelPositions(positions);
// Apply to plot
plot.setDomainAxis(categoryAxis);
// Symbol axis example
String[] symbols = {"Low", "Medium", "High", "Critical"};
SymbolAxis symbolAxis = new SymbolAxis("Priority", symbols);
symbolAxis.setRange(0, 3);
symbolAxis.setGridBandsVisible(true);
symbolAxis.setGridBandPaint(Color.LIGHT_GRAY);
symbolAxis.setGridBandAlternatePaint(Color.WHITE);
plot.setRangeAxis(symbolAxis);Additional axis types for specialized use cases and advanced features.
// Modulo axis for circular data
public class ModuloAxis extends NumberAxis {
public ModuloAxis(String label, Range displayRange);
public Range getDisplayRange();
public void setDisplayRange(Range range);
}
// Cyclic number axis
public class CyclicNumberAxis extends NumberAxis {
public CyclicNumberAxis(double period);
public CyclicNumberAxis(double period, String label);
public double getPeriod();
public void setPeriod(double period);
public boolean isBoundMappedToLastCycle();
public void setBoundMappedToLastCycle(boolean boundMappedToLastCycle);
}
// Marker axis band for highlighting ranges
public class MarkerAxisBand {
public MarkerAxisBand(CategoryAxis axis, double topOuterGap, double topInnerGap, double bottomOuterGap, double bottomInnerGap, Font font);
public void addBand(IntervalMarker band);
public void drawAxisBand(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState axisState);
}
// Timeline for custom date sequencing
public interface Timeline {
public long toTimelineValue(long millisecond);
public long toMillisecond(long timelineValue);
public boolean containsDomainValue(long millisecond);
public boolean containsDomainRange(long from, long to);
}
public class SegmentedTimeline implements Timeline {
public static final long FIRST_MONDAY_AFTER_1900 = 92073600000L;
public static final long MONDAY_TO_FRIDAY = createPointInTime(Calendar.MONDAY);
public SegmentedTimeline(long segmentSize, int segmentsIncluded, int segmentsExcluded);
public void addException(long millisecond);
public void addExceptions(List exceptions);
public void addBaseTimelineExclusions(long fromBaseline, long toBaseline);
public static SegmentedTimeline newMondayThroughFridayTimeline();
public static SegmentedTimeline newFifteenMinuteTimeline();
}Usage Example:
// Modulo axis for angular data (0-360 degrees)
ModuloAxis angleAxis = new ModuloAxis("Angle", new Range(0, 360));
angleAxis.setDisplayRange(new Range(0, 360));
angleAxis.setTickUnit(new NumberTickUnit(45)); // Every 45 degrees
plot.setDomainAxis(angleAxis);
// Timeline for business days only
SegmentedTimeline timeline = SegmentedTimeline.newMondayThroughFridayTimeline();
// Add holidays
Calendar holiday = Calendar.getInstance();
holiday.set(2023, Calendar.JULY, 4); // July 4th
timeline.addException(holiday.getTimeInMillis());
DateAxis dateAxis = new DateAxis("Business Days");
dateAxis.setTimeline(timeline);
plot.setDomainAxis(dateAxis);
// Cyclic axis for periodic data
CyclicNumberAxis cyclicAxis = new CyclicNumberAxis(24.0, "Hour of Day");
cyclicAxis.setRange(0, 24);
cyclicAxis.setTickUnit(new NumberTickUnit(6)); // Every 6 hours
plot.setDomainAxis(cyclicAxis);Install with Tessl CLI
npx tessl i tessl/maven-org-jfree--jfreechart