0
# Axes and Scales
1
2
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.
3
4
## Capabilities
5
6
### Base Axis Interface
7
8
Common functionality for all axis types including labels, tick marks, and visual appearance.
9
10
```java { .api }
11
/**
12
* Abstract base class for all axis types
13
*/
14
public abstract class Axis implements Cloneable, Serializable {
15
16
// Visibility control
17
public boolean isVisible();
18
public void setVisible(boolean flag);
19
20
// Axis label
21
public String getLabel();
22
public void setLabel(String label);
23
public Font getLabelFont();
24
public void setLabelFont(Font font);
25
public Paint getLabelPaint();
26
public void setLabelPaint(Paint paint);
27
public RectangleInsets getLabelInsets();
28
public void setLabelInsets(RectangleInsets insets);
29
public double getLabelAngle();
30
public void setLabelAngle(double angle);
31
public AxisLabelLocation getLabelLocation();
32
public void setLabelLocation(AxisLabelLocation location);
33
34
// Axis line
35
public boolean isAxisLineVisible();
36
public void setAxisLineVisible(boolean visible);
37
public Stroke getAxisLineStroke();
38
public void setAxisLineStroke(Stroke stroke);
39
public Paint getAxisLinePaint();
40
public void setAxisLinePaint(Paint paint);
41
42
// Tick labels
43
public boolean isTickLabelsVisible();
44
public void setTickLabelsVisible(boolean flag);
45
public Font getTickLabelFont();
46
public void setTickLabelFont(Font font);
47
public Paint getTickLabelPaint();
48
public void setTickLabelPaint(Paint paint);
49
public RectangleInsets getTickLabelInsets();
50
public void setTickLabelInsets(RectangleInsets insets);
51
52
// Tick marks
53
public boolean isTickMarksVisible();
54
public void setTickMarksVisible(boolean flag);
55
public float getTickMarkInsideLength();
56
public void setTickMarkInsideLength(float length);
57
public float getTickMarkOutsideLength();
58
public void setTickMarkOutsideLength(length);
59
public Stroke getTickMarkStroke();
60
public void setTickMarkStroke(Stroke stroke);
61
public Paint getTickMarkPaint();
62
public void setTickMarkPaint(Paint paint);
63
64
// Minor tick marks
65
public boolean isMinorTickMarksVisible();
66
public void setMinorTickMarksVisible(boolean flag);
67
public float getMinorTickMarkInsideLength();
68
public void setMinorTickMarkInsideLength(float length);
69
public float getMinorTickMarkOutsideLength();
70
public void setMinorTickMarkOutsideLength(float length);
71
72
// Fixed dimension
73
public double getFixedDimension();
74
public void setFixedDimension(double dimension);
75
76
// Change notification
77
public void addChangeListener(AxisChangeListener listener);
78
public void removeChangeListener(AxisChangeListener listener);
79
80
// Abstract methods
81
public abstract AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotRenderingInfo);
82
public abstract List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge);
83
}
84
```
85
86
### Value Axes
87
88
Base class for axes that display numeric values, providing range management and coordinate transformations.
89
90
```java { .api }
91
/**
92
* Abstract base class for axes that display numeric values
93
*/
94
public abstract class ValueAxis extends Axis {
95
96
// Range management
97
public Range getRange();
98
public void setRange(Range range);
99
public void setRange(double lower, double upper);
100
public double getLowerBound();
101
public void setLowerBound(double min);
102
public double getUpperBound();
103
public void setUpperBound(double max);
104
105
// Auto-ranging
106
public boolean isAutoRange();
107
public void setAutoRange(boolean auto);
108
public boolean isAutoTickUnitSelection();
109
public void setAutoTickUnitSelection(boolean flag);
110
public double getAutoRangeMinimumSize();
111
public void setAutoRangeMinimumSize(double size);
112
public double getDefaultAutoRange();
113
public void setDefaultAutoRange(Range range);
114
115
// Axis orientation
116
public boolean isInverted();
117
public void setInverted(boolean inverted);
118
119
// Margins
120
public double getLowerMargin();
121
public void setLowerMargin(double margin);
122
public double getUpperMargin();
123
public void setUpperMargin(double margin);
124
125
// Arrows
126
public boolean isPositiveArrowVisible();
127
public void setPositiveArrowVisible(boolean visible);
128
public boolean isNegativeArrowVisible();
129
public void setNegativeArrowVisible(boolean visible);
130
public Shape getUpArrow();
131
public void setUpArrow(Shape arrow);
132
public Shape getDownArrow();
133
public void setDownArrow(Shape arrow);
134
public Shape getLeftArrow();
135
public void setLeftArrow(Shape arrow);
136
public Shape getRightArrow();
137
public void setRightArrow(Shape arrow);
138
139
// Coordinate transformation
140
public abstract double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge);
141
public abstract double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge);
142
143
// Range operations
144
public void centerRange(double value);
145
public void setRangeAboutValue(double value, double length);
146
public void resizeRange(double percent);
147
public void resizeRange(double percent, double anchorValue);
148
public void resizeRange2(double percent, double anchorValue);
149
public void zoomRange(double lowerPercent, double upperPercent);
150
public void pan(double percent);
151
152
// Tick units
153
public TickUnit getTickUnit();
154
public void setTickUnit(TickUnit unit);
155
public void setTickUnit(TickUnit unit, boolean notify, boolean turnOffAutoSelection);
156
}
157
```
158
159
### Number Axis
160
161
Axis for displaying numeric values with number formatting and auto-ranging capabilities.
162
163
```java { .api }
164
/**
165
* Axis for displaying numeric values
166
*/
167
public class NumberAxis extends ValueAxis {
168
169
/**
170
* Creates a number axis with no label
171
*/
172
public NumberAxis();
173
174
/**
175
* Creates a number axis with a label
176
* @param label the axis label
177
*/
178
public NumberAxis(String label);
179
180
// Number formatting
181
public NumberFormat getNumberFormatOverride();
182
public void setNumberFormatOverride(NumberFormat formatter);
183
public RectangleInsets getTickLabelInsets();
184
public void setTickLabelInsets(RectangleInsets insets);
185
186
// Auto-range behavior
187
public boolean isAutoRangeIncludesZero();
188
public void setAutoRangeIncludesZero(boolean flag);
189
public boolean isAutoRangeStickyZero();
190
public void setAutoRangeStickyZero(boolean flag);
191
192
// Tick units
193
public TickUnitSource getStandardTickUnits();
194
public void setStandardTickUnits(TickUnitSource source);
195
public static TickUnitSource createIntegerTickUnits();
196
public static TickUnitSource createStandardTickUnits();
197
198
// Tick labels
199
public boolean isVerticalTickLabels();
200
public void setVerticalTickLabels(boolean flag);
201
202
// Range type
203
public RangeType getRangeType();
204
public void setRangeType(RangeType rangeType);
205
}
206
207
/**
208
* Logarithmic number axis
209
*/
210
public class LogAxis extends ValueAxis {
211
212
/**
213
* Creates a logarithmic axis with no label
214
*/
215
public LogAxis();
216
217
/**
218
* Creates a logarithmic axis with a label
219
* @param label the axis label
220
*/
221
public LogAxis(String label);
222
223
public double getBase();
224
public void setBase(double base);
225
public String getBaseSymbol();
226
public void setBaseSymbol(String symbol);
227
public boolean isBaseFormatter();
228
public void setBaseFormatter(boolean baseFormatter);
229
public NumberFormat getBaseFormat();
230
public void setBaseFormat(NumberFormat formatter);
231
public boolean isLogTickLabelsFlag();
232
public void setLogTickLabelsFlag(boolean flag);
233
public boolean isExpTickLabelsFlag();
234
public void setExpTickLabelsFlag(boolean flag);
235
public boolean isStrictValuesFlag();
236
public void setStrictValuesFlag(boolean flg);
237
public boolean getAllowNegativesFlag();
238
public void setAllowNegativesFlag(boolean flg);
239
}
240
```
241
242
**Usage Example:**
243
244
```java
245
import org.jfree.chart.axis.*;
246
import java.text.DecimalFormat;
247
248
// Create and customize number axis
249
NumberAxis yAxis = new NumberAxis("Revenue ($)");
250
yAxis.setRange(0, 1000000);
251
yAxis.setAutoRange(false);
252
yAxis.setAutoRangeIncludesZero(true);
253
254
// Custom number formatting
255
DecimalFormat formatter = new DecimalFormat("$#,##0");
256
yAxis.setNumberFormatOverride(formatter);
257
258
// Customize appearance
259
yAxis.setLabelFont(new Font("Arial", Font.BOLD, 14));
260
yAxis.setTickLabelFont(new Font("Arial", Font.PLAIN, 12));
261
yAxis.setLabelPaint(Color.BLUE);
262
yAxis.setTickLabelPaint(Color.BLACK);
263
264
// Set custom tick units
265
yAxis.setTickUnit(new NumberTickUnit(50000));
266
yAxis.setMinorTickMarksVisible(true);
267
268
// Apply to plot
269
plot.setRangeAxis(yAxis);
270
271
// Create logarithmic axis
272
LogAxis logAxis = new LogAxis("Log Scale");
273
logAxis.setBase(10);
274
logAxis.setStrictValuesFlag(false);
275
logAxis.setAllowNegativesFlag(false);
276
logAxis.setAutoRangeMinimumSize(1.0);
277
plot.setRangeAxis(logAxis);
278
```
279
280
### Date Axis
281
282
Axis for displaying date and time values with automatic date formatting and time zone support.
283
284
```java { .api }
285
/**
286
* Axis for displaying date and time values
287
*/
288
public class DateAxis extends ValueAxis {
289
290
/**
291
* Creates a date axis with no label
292
*/
293
public DateAxis();
294
295
/**
296
* Creates a date axis with a label
297
* @param label the axis label
298
*/
299
public DateAxis(String label);
300
301
// Date range
302
public Date getMinimumDate();
303
public void setMinimumDate(Date date);
304
public Date getMaximumDate();
305
public void setMaximumDate(Date date);
306
public Range getDefaultAutoRange();
307
public void setDefaultAutoRange(Range range);
308
309
// Date formatting
310
public DateFormat getDateFormatOverride();
311
public void setDateFormatOverride(DateFormat formatter);
312
313
// Tick units
314
public DateTickUnit getTickUnit();
315
public void setTickUnit(DateTickUnit unit);
316
public DateTickMarkPosition getTickMarkPosition();
317
public void setTickMarkPosition(DateTickMarkPosition position);
318
319
// Time zone
320
public TimeZone getTimeZone();
321
public void setTimeZone(TimeZone zone);
322
323
// Timeline support
324
public Timeline getTimeline();
325
public void setTimeline(Timeline timeline);
326
327
// Date utility methods
328
public static Date calculateLowestVisibleTickValue(DateTickUnit unit, Date lowerBound, DateTickMarkPosition tickMarkPosition, TimeZone timeZone);
329
public static Date calculateHighestVisibleTickValue(DateTickUnit unit, Date upperBound, DateTickMarkPosition tickMarkPosition, TimeZone timeZone);
330
public static Date nextStandardDate(Date date, DateTickUnit unit);
331
public static Date previousStandardDate(Date date, DateTickUnit unit);
332
}
333
334
/**
335
* Date tick unit for controlling date axis tick spacing
336
*/
337
public class DateTickUnit extends TickUnit {
338
339
/**
340
* Creates a date tick unit
341
* @param unitType the date unit type (YEAR, MONTH, DAY, etc.)
342
* @param multiple the multiple of the unit type
343
*/
344
public DateTickUnit(DateTickUnitType unitType, int multiple);
345
346
/**
347
* Creates a date tick unit with custom formatting
348
* @param unitType the date unit type
349
* @param multiple the multiple of the unit type
350
* @param formatter the date formatter
351
*/
352
public DateTickUnit(DateTickUnitType unitType, int multiple, DateFormat formatter);
353
354
public DateTickUnitType getUnitType();
355
public int getMultiple();
356
public long getMillisecondCount();
357
public DateFormat getFormatter();
358
public String dateToString(Date date);
359
360
// Calendar field constants
361
public static final DateTickUnitType YEAR = new DateTickUnitType("YEAR", Calendar.YEAR);
362
public static final DateTickUnitType MONTH = new DateTickUnitType("MONTH", Calendar.MONTH);
363
public static final DateTickUnitType DAY = new DateTickUnitType("DAY", Calendar.DATE);
364
public static final DateTickUnitType HOUR = new DateTickUnitType("HOUR", Calendar.HOUR_OF_DAY);
365
public static final DateTickUnitType MINUTE = new DateTickUnitType("MINUTE", Calendar.MINUTE);
366
public static final DateTickUnitType SECOND = new DateTickUnitType("SECOND", Calendar.SECOND);
367
public static final DateTickUnitType MILLISECOND = new DateTickUnitType("MILLISECOND", Calendar.MILLISECOND);
368
}
369
370
/**
371
* Period axis for displaying time periods
372
*/
373
public class PeriodAxis extends ValueAxis {
374
375
/**
376
* Creates a period axis
377
* @param label the axis label
378
*/
379
public PeriodAxis(String label);
380
381
/**
382
* Creates a period axis with time zone
383
* @param label the axis label
384
* @param first the first period
385
* @param last the last period
386
*/
387
public PeriodAxis(String label, RegularTimePeriod first, RegularTimePeriod last);
388
389
public RegularTimePeriod getFirst();
390
public void setFirst(RegularTimePeriod first);
391
public RegularTimePeriod getLast();
392
public void setLast(RegularTimePeriod last);
393
public TimeZone getTimeZone();
394
public void setTimeZone(TimeZone timeZone);
395
public boolean isAutoRangeTimePeriodClass();
396
public void setAutoRangeTimePeriodClass(Class timePeriodClass);
397
public PeriodAxisLabelInfo[] getLabelInfo();
398
public void setLabelInfo(PeriodAxisLabelInfo[] info);
399
}
400
```
401
402
**Usage Example:**
403
404
```java
405
import org.jfree.chart.axis.*;
406
import org.jfree.data.time.*;
407
import java.text.SimpleDateFormat;
408
import java.util.TimeZone;
409
410
// Create date axis
411
DateAxis timeAxis = new DateAxis("Time");
412
413
// Set date range
414
Calendar cal = Calendar.getInstance();
415
cal.set(2023, Calendar.JANUARY, 1);
416
Date startDate = cal.getTime();
417
cal.set(2023, Calendar.DECEMBER, 31);
418
Date endDate = cal.getTime();
419
420
timeAxis.setMinimumDate(startDate);
421
timeAxis.setMaximumDate(endDate);
422
423
// Custom date formatting
424
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM yyyy");
425
timeAxis.setDateFormatOverride(dateFormat);
426
427
// Set tick unit
428
timeAxis.setTickUnit(new DateTickUnit(DateTickUnitType.MONTH, 1));
429
timeAxis.setTickMarkPosition(DateTickMarkPosition.START);
430
431
// Time zone support
432
timeAxis.setTimeZone(TimeZone.getTimeZone("America/New_York"));
433
434
// Apply to plot
435
plot.setDomainAxis(timeAxis);
436
437
// Period axis example
438
PeriodAxis periodAxis = new PeriodAxis("Quarters");
439
periodAxis.setFirst(new Quarter(1, 2023));
440
periodAxis.setLast(new Quarter(4, 2024));
441
periodAxis.setTimeZone(TimeZone.getDefault());
442
443
// Configure period labels
444
PeriodAxisLabelInfo[] labelInfo = new PeriodAxisLabelInfo[2];
445
labelInfo[0] = new PeriodAxisLabelInfo(Quarter.class, new SimpleDateFormat("Q"));
446
labelInfo[1] = new PeriodAxisLabelInfo(Year.class, new SimpleDateFormat("yyyy"));
447
periodAxis.setLabelInfo(labelInfo);
448
```
449
450
### Category Axis
451
452
Axis for displaying categorical labels with support for label positioning and rotation.
453
454
```java { .api }
455
/**
456
* Axis for displaying category labels
457
*/
458
public class CategoryAxis extends Axis {
459
460
/**
461
* Creates a category axis with no label
462
*/
463
public CategoryAxis();
464
465
/**
466
* Creates a category axis with a label
467
* @param label the axis label
468
*/
469
public CategoryAxis(String label);
470
471
// Margins
472
public double getLowerMargin();
473
public void setLowerMargin(double margin);
474
public double getUpperMargin();
475
public void setUpperMargin(double margin);
476
public double getCategoryMargin();
477
public void setCategoryMargin(double margin);
478
479
// Label display
480
public int getMaximumCategoryLabelLines();
481
public void setMaximumCategoryLabelLines(int lines);
482
public float getMaximumCategoryLabelWidthRatio();
483
public void setMaximumCategoryLabelWidthRatio(float ratio);
484
public int getCategoryLabelPositionOffset();
485
public void setCategoryLabelPositionOffset(int offset);
486
487
// Label positioning
488
public CategoryLabelPositions getCategoryLabelPositions();
489
public void setCategoryLabelPositions(CategoryLabelPositions positions);
490
public boolean isVerticalCategoryLabels();
491
public void setVerticalCategoryLabels(boolean flag);
492
493
// Coordinate calculations
494
public double getCategoryStart(int category, int categoryCount, Rectangle2D area, RectangleEdge edge);
495
public double getCategoryMiddle(int category, int categoryCount, Rectangle2D area, RectangleEdge edge);
496
public double getCategoryEnd(int category, int categoryCount, Rectangle2D area, RectangleEdge edge);
497
public double getCategorySeriesMiddle(int categoryIndex, int categoryCount, int seriesIndex, int seriesCount, double itemMargin, Rectangle2D area, RectangleEdge edge);
498
499
// Java2D coordinate conversion
500
public double categoryToJava2D(Comparable category, Rectangle2D area, RectangleEdge edge);
501
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge);
502
public Comparable java2DToCategory(double java2DValue, Rectangle2D area, RectangleEdge edge);
503
}
504
505
/**
506
* Sub-category axis for hierarchical categories
507
*/
508
public class SubCategoryAxis extends CategoryAxis {
509
510
/**
511
* Creates a sub-category axis
512
* @param label the axis label
513
*/
514
public SubCategoryAxis(String label);
515
516
public void addSubCategory(Comparable subcategory);
517
public List getSubCategories();
518
public Paint getSubLabelPaint();
519
public void setSubLabelPaint(Paint paint);
520
public Font getSubLabelFont();
521
public void setSubLabelFont(Font font);
522
}
523
524
/**
525
* Extended category axis with additional features
526
*/
527
public class ExtendedCategoryAxis extends CategoryAxis {
528
529
/**
530
* Creates an extended category axis
531
* @param label the axis label
532
*/
533
public ExtendedCategoryAxis(String label);
534
535
public Map getSubLabelFonts();
536
public void setSubLabelFont(Comparable category, Font font);
537
public Font getSubLabelFont(Comparable category);
538
public Map getSubLabelPaints();
539
public void setSubLabelPaint(Comparable category, Paint paint);
540
public Paint getSubLabelPaint(Comparable category);
541
}
542
543
/**
544
* Symbol axis for displaying symbol-based labels
545
*/
546
public class SymbolAxis extends NumberAxis {
547
548
/**
549
* Creates a symbol axis
550
* @param label the axis label
551
* @param sv the list of symbols
552
*/
553
public SymbolAxis(String label, String[] sv);
554
555
public String[] getSymbols();
556
public void setSymbols(String[] symbols);
557
public boolean isGridBandsVisible();
558
public void setGridBandsVisible(boolean flag);
559
public Paint getGridBandPaint();
560
public void setGridBandPaint(Paint paint);
561
public Paint getGridBandAlternatePaint();
562
public void setGridBandAlternatePaint(Paint paint);
563
}
564
```
565
566
**Usage Example:**
567
568
```java
569
import org.jfree.chart.axis.*;
570
571
// Create category axis
572
CategoryAxis categoryAxis = new CategoryAxis("Products");
573
574
// Configure margins
575
categoryAxis.setLowerMargin(0.02);
576
categoryAxis.setUpperMargin(0.02);
577
categoryAxis.setCategoryMargin(0.10);
578
579
// Configure label display
580
categoryAxis.setMaximumCategoryLabelLines(3);
581
categoryAxis.setMaximumCategoryLabelWidthRatio(0.8f);
582
583
// Configure label positioning for angled labels
584
CategoryLabelPositions positions = new CategoryLabelPositions(
585
new CategoryLabelPosition(RectangleAnchor.BOTTOM_LEFT, TextAnchor.BOTTOM_LEFT,
586
TextAnchor.BOTTOM_LEFT, -Math.PI / 4.0),
587
new CategoryLabelPosition(RectangleAnchor.TOP_LEFT, TextAnchor.TOP_LEFT,
588
TextAnchor.TOP_LEFT, -Math.PI / 4.0),
589
new CategoryLabelPosition(RectangleAnchor.BOTTOM_RIGHT, TextAnchor.BOTTOM_RIGHT,
590
TextAnchor.BOTTOM_RIGHT, Math.PI / 4.0),
591
new CategoryLabelPosition(RectangleAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT,
592
TextAnchor.TOP_RIGHT, Math.PI / 4.0)
593
);
594
categoryAxis.setCategoryLabelPositions(positions);
595
596
// Apply to plot
597
plot.setDomainAxis(categoryAxis);
598
599
// Symbol axis example
600
String[] symbols = {"Low", "Medium", "High", "Critical"};
601
SymbolAxis symbolAxis = new SymbolAxis("Priority", symbols);
602
symbolAxis.setRange(0, 3);
603
symbolAxis.setGridBandsVisible(true);
604
symbolAxis.setGridBandPaint(Color.LIGHT_GRAY);
605
symbolAxis.setGridBandAlternatePaint(Color.WHITE);
606
plot.setRangeAxis(symbolAxis);
607
```
608
609
### Specialized Axes
610
611
Additional axis types for specialized use cases and advanced features.
612
613
```java { .api }
614
// Modulo axis for circular data
615
public class ModuloAxis extends NumberAxis {
616
public ModuloAxis(String label, Range displayRange);
617
public Range getDisplayRange();
618
public void setDisplayRange(Range range);
619
}
620
621
// Cyclic number axis
622
public class CyclicNumberAxis extends NumberAxis {
623
public CyclicNumberAxis(double period);
624
public CyclicNumberAxis(double period, String label);
625
public double getPeriod();
626
public void setPeriod(double period);
627
public boolean isBoundMappedToLastCycle();
628
public void setBoundMappedToLastCycle(boolean boundMappedToLastCycle);
629
}
630
631
// Marker axis band for highlighting ranges
632
public class MarkerAxisBand {
633
public MarkerAxisBand(CategoryAxis axis, double topOuterGap, double topInnerGap, double bottomOuterGap, double bottomInnerGap, Font font);
634
public void addBand(IntervalMarker band);
635
public void drawAxisBand(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState axisState);
636
}
637
638
// Timeline for custom date sequencing
639
public interface Timeline {
640
public long toTimelineValue(long millisecond);
641
public long toMillisecond(long timelineValue);
642
public boolean containsDomainValue(long millisecond);
643
public boolean containsDomainRange(long from, long to);
644
}
645
646
public class SegmentedTimeline implements Timeline {
647
public static final long FIRST_MONDAY_AFTER_1900 = 92073600000L;
648
public static final long MONDAY_TO_FRIDAY = createPointInTime(Calendar.MONDAY);
649
650
public SegmentedTimeline(long segmentSize, int segmentsIncluded, int segmentsExcluded);
651
public void addException(long millisecond);
652
public void addExceptions(List exceptions);
653
public void addBaseTimelineExclusions(long fromBaseline, long toBaseline);
654
655
public static SegmentedTimeline newMondayThroughFridayTimeline();
656
public static SegmentedTimeline newFifteenMinuteTimeline();
657
}
658
```
659
660
**Usage Example:**
661
662
```java
663
// Modulo axis for angular data (0-360 degrees)
664
ModuloAxis angleAxis = new ModuloAxis("Angle", new Range(0, 360));
665
angleAxis.setDisplayRange(new Range(0, 360));
666
angleAxis.setTickUnit(new NumberTickUnit(45)); // Every 45 degrees
667
plot.setDomainAxis(angleAxis);
668
669
// Timeline for business days only
670
SegmentedTimeline timeline = SegmentedTimeline.newMondayThroughFridayTimeline();
671
// Add holidays
672
Calendar holiday = Calendar.getInstance();
673
holiday.set(2023, Calendar.JULY, 4); // July 4th
674
timeline.addException(holiday.getTimeInMillis());
675
676
DateAxis dateAxis = new DateAxis("Business Days");
677
dateAxis.setTimeline(timeline);
678
plot.setDomainAxis(dateAxis);
679
680
// Cyclic axis for periodic data
681
CyclicNumberAxis cyclicAxis = new CyclicNumberAxis(24.0, "Hour of Day");
682
cyclicAxis.setRange(0, 24);
683
cyclicAxis.setTickUnit(new NumberTickUnit(6)); // Every 6 hours
684
plot.setDomainAxis(cyclicAxis);
685
```