【问题标题】:JFreeChart CategoryPlot overwrites categoriesJFreeChart CategoryPlot 覆盖类别
【发布时间】:2025-12-09 10:00:02
【问题描述】:

我是使用 JFreeChart 的新手,我确信我的问题有一个简单的解决方案。 .

问题:
我有一个图表,沿日期 X 轴显示多个“事件类型”。 Y 轴显示“事件类别”。我的问题是每个类别只显示事件类型的最新日期。

在下面的示例中,图表显示了事件类型 1 在 6 月 20 日(类别 1)和 6 月 10 日(类别 2)的数据点。我还添加了 6 月 10 日的数据点,类别 1,但 6 月 20 日的数据点将其删除。

我想我误解了 CategoryPlot 的工作原理。我是否使用了错误类型的图表?我认为散点图是票,但它只接受数值。我需要在我的 Y 轴上有离散的字符串类别。

如果有人能指出我正确的方向,你真的会让我很开心。感谢阅读!

-克里斯汀

(下面的代码按原样工作。它尽可能简单)

import java.awt.Dimension;

import javax.swing.JPanel;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.time.Day;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class EventFrequencyDemo1 extends ApplicationFrame   
{   
    public EventFrequencyDemo1(String s)   
    {   
        super(s);   
        CategoryDataset categorydataset = createDataset();   
        JFreeChart jfreechart = createChart(categorydataset);   
        ChartPanel chartpanel = new ChartPanel(jfreechart);   
        chartpanel.setPreferredSize(new Dimension(500, 270));   
        setContentPane(chartpanel);   
    }   

    private static JFreeChart createChart(CategoryDataset categorydataset)   
    {   
        CategoryPlot categoryplot = new CategoryPlot(categorydataset, new CategoryAxis("Category"), new DateAxis("Date"), new LineAndShapeRenderer(false, true));
        categoryplot.setOrientation(PlotOrientation.HORIZONTAL);
        categoryplot.setDomainGridlinesVisible(true);
        return new JFreeChart(categoryplot);   
    }   

    private static CategoryDataset createDataset()   
    {   
        DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();   
        Day june10 = new Day(10, 6, 2002);   
        Day june20 = new Day(20, 6, 2002);
        // This event is overwritten by June20th
        defaultcategorydataset.setValue(new Long(june10.getMiddleMillisecond()), "Event Type 1", "Category 1");   
        defaultcategorydataset.setValue(new Long(june10.getMiddleMillisecond()), "Event Type 1", "Category 2");   
        // Overwrites the previous June10th event
        defaultcategorydataset.setValue(new Long(june20.getMiddleMillisecond()), "Event Type 1", "Category 1");   
        defaultcategorydataset.setValue(new Long(june20.getMiddleMillisecond()), "Event Type 2", "Category 2");   
        return defaultcategorydataset;   
    }   

    public static JPanel createDemoPanel()   
    {   
        JFreeChart jfreechart = createChart(createDataset());   
        return new ChartPanel(jfreechart);   
    }   

    public static void main(String args[])   
    {   
        EventFrequencyDemo1 eventfrequencydemo1 = new EventFrequencyDemo1("Event Frequency Demo");   
        eventfrequencydemo1.pack();   
        RefineryUtilities.centerFrameOnScreen(eventfrequencydemo1);   
        eventfrequencydemo1.setVisible(true);   
    }   
}  

【问题讨论】:

    标签: java jfreechart graphing


    【解决方案1】:

    除了@Jeff Storey 的建议之外,您还可以从JFreeChart Samples 中获得一些灵感,并且不要忽视Demo 应用程序,该应用程序可通过Java Web Start 获得。我不确定我是否符合您的要求,但 DefaultMultiValueCategoryDataset 被描述为“为每个项目定义多个值的类别数据集。”

    附录:如果你想坚持使用LineAndShapeRendererLineAndShapeRenderer(false, true)setBaseLinesVisible() 都可以排除画线。

    【讨论】:

    • 谢谢!使用 DefaultMultiValueCategoryDataset 让我成功了一半。我必须做的另一件事是使用 ScatterRenderer 而不是 LineAndShapeRenderer。我现在遇到自动量程太窄的问题,但我必须进一步研究。再次感谢你们两位的精彩帮助! :) -克里斯汀
    • 太棒了!我没有用过ScatterRenderer,但我在上面评论过LineAndShapeRenderer。另见*.com/questions/2081676/…
    【解决方案2】:

    我认为您在这里使用了错误类型的数据集和图表。您似乎正在尝试创建散点图,因此您应该使用散点图而不是类别图。在类别图中,因为每一行/列对只得到一个值。因此,在第一次调用中,您说 event1/category1 对的值为 june10.getMiddleMillisecond,然后您将其值更改为 june20.getMiddleMillisecond。您可能还想查看时间序列图。

    【讨论】:

    • 谢谢 Jeff,我开始感觉到问题出在哪里。我查看了散点图,但据我所知,我只能将 float[][] 用于数据集。如何使用字符串(类别)而不是浮点数来绘制 y 轴?如果没有情节可以做我正在寻找的东西,也许我需要编写自己的自定义类?如果是这样的话,有没有人建议一个开始学习这个的好地方?谢谢! -克里斯汀
    • 您可以使用 CategoryTableXYDataset。我知道它需要 x、y 值,但您可以编写自定义轴渲染器(如果需要,还可以编写自定义图例 0 以便轴上的基础值是数字,但它们呈现为字符串。例如,y 轴可能有值 1、2 和 3,但渲染器会将它们渲染为 6 月 1 日、6 月 2 日、6 月 3 日。这不是一个理想的解决方案,但您尝试创建的图表类型并不真正适合现有的 JFreeChart 图并且可能比编写自己的情节更容易。