java - 次要域轴比主域轴窄

标签 java jfreechart

我的 timeSeries 包含两天内网页的访问者数量,然后引用 timeSeries 包含其他两天内网页的访问者数量。我成功地将这些数据集放入一张图表中,但似乎我添加的辅助域轴要窄得多,因此无法比较这些值。

enter image description here

我可以将这些轴的宽度设置为相同吗?

编辑:我在下面发布了创建 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;
}

最佳答案

您的片段中显示的比较方法似乎是合理的,但我怀疑您看不见的数据在给定的每小时间隔内有多个不同的时间戳,DateAxis忠实地报告了这些时间戳.

下面的变体清除了较小的Calendar字段,如图here ,合成相当于 DAYS 的数据。生成的 Hour 实例在每个系列中都有匹配的小时字段。该示例还省略了 ChartFactory 以避免出现不需要的 ChartTheme 轴标签字体。

要获得您想要的结果,您必须重新采样您的数据,以便为您add()<的每个period提供匹配的小时字段TimeSeries

image

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);
    }
}

关于java - 次要域轴比主域轴窄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55553082/

相关文章:

java - 如何将参数(用户名和密码)传递给函数signinactivity

java - 如何使用Java在单个终端中执行多个命令?

java - 正在生成 PDF 报告 : jFreeChart and DynamicReports

java - JFreeChart 直方图在缩放时具有恒定数量的 bin

java - byte[] 到 string 以及 String 到 byte[] 保持信息不变

javascript - 无法从 HTTP GET 获取数据 - Javascript

exception - JFreechart 系列异常

java - jFreeChart : Customizing the linear chart axis labels

java - 关于 hibernate 和 JFreechart 的问题

java - 在 itext 7 中将 html 转换为 pdf 时如何仅获得某些页面的横向方向?