Reputation: 103
I have timeSeries containing number of visitors for a web page in two days and then referential timeSeries containing number of visitors for a web page in other two days. I successfully put these datasets into one chart, but it seems that secondary domain axis I added is much narrower and thus it is impossible to compare those values.
Can I set the width of those axes to be the same?
EDIT: I posted my method to create JFreeChart down below. There is 48 values for both datasets.
public JFreeChart HourChart(CampaignWatcher choosenWatcher) throws UnknownHostException {
ArrayList<ArrayList<HourObject>> data = GetWatcherData(choosenWatcher);
TimeSeries timeSeries = new TimeSeries("Number of visitors");
TimeSeries timeSeriesRef = new TimeSeries("Referential number of visitors");
for(int i = 0; i<data.get(0).size();i++) {
timeSeries.add(new Hour(data.get(0).get(i).hour,data.get(0).get(i).day,data.get(0).get(i).month,data.get(0).get(i).year),data.get(0).get(i).logObjects.size());
}
if(choosenWatcher.compareWithRef){
for(int i = 0; i<data.get(1).size();i++) {
timeSeriesRef.add(new Hour(data.get(1).get(i).hour,data.get(1).get(i).day,data.get(1).get(i).month,data.get(1).get(i).year),data.get(1).get(i).logObjects.size());
}
}
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(timeSeries);
JFreeChart timeChart = ChartFactory.createTimeSeriesChart(choosenWatcher.name,"Hours","Number of visitors",dataset);
timeChart.setBackgroundPaint(Color.white);
XYPlot plot = (XYPlot) timeChart.getPlot();
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
//plot.setDomainCrosshairVisible(true);
//plot.setRangeCrosshairVisible(true);
XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setDefaultLinesVisible(true);
renderer.setDefaultShapesFilled(true);
renderer.setDrawSeriesLineAsPath(true);
}
DateAxis axis = (DateAxis) plot.getDomainAxis();
axis.setDateFormatOverride(new SimpleDateFormat("dd/MMM/yyyy HH"));
DateAxis axisRef = new DateAxis("Referential hours");
axisRef.setDateFormatOverride(new SimpleDateFormat("dd/MMM/yyyy HH"));
plot.setDomainAxis(1, axisRef);
plot.setDomainAxisLocation(1,AxisLocation.BOTTOM_OR_RIGHT);
TimeSeriesCollection datasetRef = new TimeSeriesCollection();
datasetRef.addSeries(timeSeriesRef);
plot.setDataset(1,datasetRef);
plot.mapDatasetToDomainAxis(1,1);
plot.mapDatasetToRangeAxis(1,0);
XYLineAndShapeRenderer renderer0 = new XYLineAndShapeRenderer();
XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer();
plot.setRenderer(0, renderer0);
plot.setRenderer(1, renderer1);
plot.getRendererForDataset(plot.getDataset(0)).setSeriesPaint(0, Color.red);
plot.getRendererForDataset(plot.getDataset(1)).setSeriesPaint(0, Color.blue);
plot.setDomainPannable(true);
plot.setRangePannable(true);
ValueAxis valAxis = plot.getRangeAxis();
valAxis.setAutoRange(true);
return timeChart;
}
Upvotes: 2
Views: 146
Reputation: 205785
The comparison approach shown in your fragment appears sound, but I suspect that your unseen data
has multiple, varying timestamps for a given hourly interval, which the DateAxis
faithfully reports.
The variation below clears the smaller Calendar
fields, as shown here, to synthesize a DAYS
worth of data. The resulting Hour
instances have matching hour fields in each series. The example also omits the ChartFactory
to avoid the unwanted ChartTheme
axis label font.
To get the result you want, you're going have to resample your data
to have matching hour fields for each period
that you add()
to a TimeSeries
.
import java.awt.Color;
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
/**
* @see https://stackoverflow.com/a/55584636/230513
* @see https://stackoverflow.com/q/55553082/230513
*/
public class HourTest {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MMM HH");
private static final int DAYS = 1;
private Calendar getCalendar() {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);return c;
}
private void display() {
JFrame f = new JFrame("HourTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TimeSeries timeSeries = new TimeSeries("Number of visitors");
TimeSeries refSeries = new TimeSeries("Reference number of visitors");
Calendar c1 = getCalendar();
Calendar c2 = getCalendar();
c2.add(Calendar.DAY_OF_YEAR, -DAYS);
for (int i = 0; i < 24 * DAYS; i++) {
timeSeries.add(new Hour(c1.getTime()), i + 2);
c1.add(Calendar.HOUR, 1);
refSeries.add(new Hour(c2.getTime()), i + 1);
c2.add(Calendar.HOUR, 1);
}
TimeSeriesCollection dataset = new TimeSeriesCollection(timeSeries);
TimeSeriesCollection refDataset = new TimeSeriesCollection(refSeries);
NumberAxis valueAxis = new NumberAxis("Number of visitors");
valueAxis.setAutoRangeIncludesZero(false);
DateAxis timeAxis = new DateAxis("Hours");
timeAxis.setDateFormatOverride(DATE_FORMAT);
DateAxis refAxis = new DateAxis("Reference hours");
refAxis.setDateFormatOverride(DATE_FORMAT);
XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, null);
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
plot.setDomainAxis(1, refAxis);
plot.setDomainAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);
plot.setDataset(1, refDataset);
plot.mapDatasetToDomainAxis(1, 1);
XYLineAndShapeRenderer renderer0 = new XYLineAndShapeRenderer();
renderer0.setSeriesPaint(0, Color.red);
XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer();
renderer1.setSeriesPaint(0, Color.blue);
plot.setRenderer(0, renderer0);
plot.setRenderer(1, renderer1);
plot.setDomainPannable(true);
plot.setRangePannable(true);
JFreeChart timeChart = new JFreeChart("Main stats", plot);
timeChart.setBackgroundPaint(Color.white);
f.add(new ChartPanel(timeChart));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new HourTest()::display);
}
}
Upvotes: 2