У меня есть временной ряд, содержащий количество посетителей веб-страницы за два дня, а затем ссылочный временной ряд, содержащий количество посетителей веб-страницы в другие два дня. Я успешно поместил эти наборы данных в одну диаграмму, но кажется, что дополнительная ось домена, которую я добавил, намного уже, и поэтому невозможно сравнить эти значения.
Могу ли я установить ширину этих осей одинаковой?
Обновлено: я разместил свой метод для создания JFreeChart ниже. Для обоих наборов данных имеется 48 значений.
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;
}
Как вы можете видеть на картинке, хотя обе эти диаграммы должны отображать 48 часов. Однако синяя линия диаграммы заканчивается раньше, чем красная линия, синие кружки не находятся в том же положении (на оси домена), что и красные прямоугольники.
Я предполагаю, что времена разные; ваш минимальный воспроизводимый пример может пояснить.
@trashgod да, есть данные с 21 по 22 марта (красный) и с 23 по 24 марта (синий). Но есть такое же количество часов.
Посмотрите на каждую метку времени в миллисекундах из эпоха.
Подход к сравнению, показанный в вашем фрагменте, выглядит разумным, но я подозреваю, что ваш невидимый data
имеет несколько разных временных меток для заданного часового интервала, о чем DateAxis
точно сообщает.
Вариант ниже очищает меньшие поля Calendar
, как показано здесь, для синтеза данных DAYS
. Полученные экземпляры Hour
имеют совпадающие поля часов в каждой серии. В примере также отсутствует ChartFactory
, чтобы избежать нежелательного шрифта метки оси ChartTheme
.
Чтобы получить желаемый результат, вам придется повторно сэмплировать ваши data
, чтобы для каждого period
, которое вы add()
, совпадали с 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);
}
}
Также рассмотрите гистограмму, видимую здесь, для простоты сравнения.
Несмотря на использование разных шрифтов, оси идентичны по длине экрана и временному интервалу. Интервалы кажутся последовательными, и я вижу, что оба показывают меньше посетителей ночью и больше днем. Что вы ожидали увидеть? В любом случае, пожалуйста, редактировать вашего вопроса, чтобы включить минимальный воспроизводимый пример, который показывает диаграмму, которую вы иллюстрируете.