From what I can tell DateTickUnitType is an enumeration that cannot be extended or changed outside of outright replacement and it only specifies units for DAY, MONTH, YEAR, MINUTE, HOUR, SECOND, and MILLISECOND, but not WEEK despite there being a Week type of TimePeriod.
The problem this causes is when I am forced to use the DAY tick unit to plot a single data point for a week which leaves my bar width quite narrow as compared to plotting a daily point on a DAY tick unit or a monthly data point on a MONTH tick unit.
Depending on the range of my data (which I calculate programmatically), I create the TimeSeriesDataItem with the most appropriate TimePeriod:
// create the correct TimeSeriesDataItem based on the gap of this data set
switch (gap) {
case WEEK:
item = new TimeSeriesDataItem(new Week(targetDate.getTime()), dataPoint);
break;
case DAY:
item = new TimeSeriesDataItem(new Day(targetDate.getTime()), dataPoint);
break;
case MONTH:
default:
item = new TimeSeriesDataItem(new Month(targetDate.getTime()), dataPoint);
break;
}
And then after the chart is built, I try to customize it to make the bars as wide as possible for each data point. If the data are days, the tick units are days. If the data are months, the tick units are months. But if the data are weeks, then I’m forced to either go with days or months since there is no week tick unit.
JFreeChart barChart = ChartFactory.createXYBarChart(
model.getTitle(),
model.getDomainTitle(),
true,
model.getRangeTitle(),
dataset,
model.getOrientation() == SimpleBarChartModel.Orientation.VERTICAL ? PlotOrientation.VERTICAL : PlotOrientation.HORIZONTAL,
model.getShowLegend(),
false,
false);
// ...
DateAxis domainAxis = (DateAxis)plot.getDomainAxis();
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
if (model.getDomainLabels() != null && model.getDomainLabels().size() > 1) {
// create three different sets of TickUnits for the three ranges (day, week, month)
// JFreeChart will select the smallest unit that doesn't overlap labels.
TickUnits tickUnits = new TickUnits();
tickUnits.add(new DateTickUnit(DateTickUnitType.MONTH, 1, new SimpleDateFormat("MMM")));
tickUnits.add(new DateTickUnit(DateTickUnitType.DAY, 7, dateFormat));
tickUnits.add(new DateTickUnit(DateTickUnitType.DAY, 1, dateFormat));
domainAxis.setStandardTickUnits(tickUnits);
}
domainAxis.setAutoRange(true);
domainAxis.setVerticalTickLabels(true);
domainAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
The former creates very thin bars since it’s plotting 7 columns per tick unit.
Is there any way for me to make a custom DateTickUnitType for WEEK that would allow me to plot only one point per week instead of 7 (since I only have one data point)?
For
DynamicTimeSeriesCollectionyou can addWEEKusing the approach shown here forMILLISECOND. See also this followup thread, which mentions multiples of the chosen period.