JFreeChart:自定义 BoxAndWhisker 图表

2023-11-29

我开始使用JFreeChart做一些策划。 我希望我的图表如下图所示:

Interval graph

我非常接近使用BoxAndWhisker chart:

my graph

然而,有些事情我仍然想改变。有没有办法去掉盒子,这样我就只有中间线了?如何向条形图添加标签?另外,由于某种原因,y 轴的最后一个数字(图像右下角)被切断。

这是我的示例代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import javax.swing.Icon;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.CategoryItemRendererState;
import org.jfree.chart.renderer.category.MinMaxCategoryRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;

public class MinMaxCategoryPlotTest extends ApplicationFrame {

    public MinMaxCategoryPlotTest(String title) {

        super(title);

        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(1604, "1", "PESAII");
        dataset.addValue(1704, "2", "PESAII");
        dataset.addValue(1804, "3", "PESAII");

        dataset.addValue(1512, "1", "NSGAII");
        dataset.addValue(1612, "2", "NSGAII");
        dataset.addValue(1712, "3", "NSGAII");

        dataset.addValue(1436, "1", "SPEA2");
        dataset.addValue(1536, "2", "SPEA2");
        dataset.addValue(1636, "3", "SPEA2");

        dataset.addValue(1363, "1", "IBEA");
        dataset.addValue(1463, "2", "IBEA");
        dataset.addValue(1563, "3", "IBEA");

        dataset.addValue(1186, "1", "MOEA/D");
        dataset.addValue(1286, "2", "MOEA/D");
        dataset.addValue(1386, "3", "MOEA/D");

        final CategoryAxis xAxis = new CategoryAxis("");
        xAxis.setTickLabelsVisible(false);

        final NumberAxis yAxis = new NumberAxis("Rating");
        yAxis.setRange(1100, 2000);

        DecimalFormat df = new DecimalFormat("0"); // Override the decimal format to get integer numbers on the axis (1.800 -> 1800)
        yAxis.setNumberFormatOverride(df);
        yAxis.setAutoRangeIncludesZero(false);

        MyMinMaxCategoryRenderer renderer = new MyMinMaxCategoryRenderer();

        renderer.setSeriesPaint(0, new Color(0, 0, 0, 0)); // invisible
        renderer.setSeriesPaint(1, Color.black);
        renderer.setSeriesPaint(2, new Color(0, 0, 0, 0)); // invisible

        renderer.setSeriesShape(1, new Line2D.Double(0, -6, 0, 6)); //not working
        renderer.setSeriesVisible(0, false); // not working

        renderer.setMinIcon(getIcon(new Line2D.Double(0, -6, 0, 6), true, true));
        renderer.setMaxIcon(getIcon(new Line2D.Double(0, -6, 0, 6), true, true));
        renderer.setObjectIcon(getIcon(new Line2D.Double(0, -4, 0, 4), true, true));

        final CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);
        plot.setOrientation(PlotOrientation.HORIZONTAL);
        plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);

        final JFreeChart chart = new JFreeChart(
            title,
            new Font("SansSerif", Font.BOLD, 16),
            plot,
            false
        );

        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(1000, 400));
        setContentPane(chartPanel);

        chart.setBackgroundPaint(Color.white);

        chart.setPadding(new RectangleInsets(10, 10, 10, 10)); // Fix: tick label cut off

    }

    private Icon getIcon(Shape shape, final boolean fill,
        final boolean outline) {
        final int width = shape.getBounds().width;
        final int height = shape.getBounds().height;
        final GeneralPath path = new GeneralPath(shape);
        return new Icon() {
            public void paintIcon(Component c, Graphics g, int x, int y) {
                Graphics2D g2 = (Graphics2D) g;
                path.transform(AffineTransform.getTranslateInstance(x, y));
                if (fill) {
                    g2.fill(path);
                }
                if (outline) {
                    g2.draw(path);
                }
                path.transform(AffineTransform.getTranslateInstance(-x, -y));
            }

            public int getIconWidth() {
                return width;
            }

            public int getIconHeight() {
                return height;
            }
        };
    }

    public static void main(String[] args) {

        MinMaxCategoryPlotTest demo = new MinMaxCategoryPlotTest("Rating Interval");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);

    }

    public class MyMinMaxCategoryRenderer extends MinMaxCategoryRenderer {

        @Override
        public void drawItem(Graphics2D g2, CategoryItemRendererState state,
            Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis,
            ValueAxis rangeAxis, CategoryDataset dataset, int row, int column,
            int pass) {
            super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass);

            //Draw label
            if (dataset.getRowCount() - 1 == row) { //last row

                Number value = dataset.getValue(row, column);
                double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
                    dataArea, plot.getDomainAxisEdge());
                double y1 = rangeAxis.valueToJava2D(value.doubleValue(), dataArea,
                    plot.getRangeAxisEdge());

                g2.setFont(new Font("SansSerif", Font.BOLD, 14));
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                String name = dataset.getColumnKey(column).toString();
                int width = g2.getFontMetrics().stringWidth(name);

                g2.drawString(name, (int) y1 - width, (int) x1 - 12);

            }
        }

    }
}

Final complete result for Rating / Confidence Intervals: Final result


代替BoxAndWhiskerRenderer,检查了here, use a MinMaxCategoryRenderer with PlotOrientation.HORIZONTAL和一个习惯AxisLocation.

CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setOrientation(PlotOrientation.HORIZONTAL);
MinMaxCategoryRenderer renderer = new MinMaxCategoryRenderer();
plot.setRenderer(renderer);
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);

image

您可以更改Icon像这样使用,或者您可以基于创建自己的图标这种方法.

renderer.setObjectIcon(renderer.getMinIcon());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JFreeChart:自定义 BoxAndWhisker 图表 的相关文章

  • JNA - EnumProcessModules() 未返回所有 DLL?

    我试图从游戏中读取坐标 当我在通过 OpenProcess 接收的 HANDLE 上使用 ReadProcessMemory 以及我在 CheatEngine 中找到的内存时 效果非常好 例如 如果我知道正在运行的进程中的浮点值是0x5AB
  • 检查发送到网页的请求数

    我正在编写一个 Java 多线程应用程序 它可以访问不同 Web 服务器的数百万个 有时甚至数十亿个 URL 这个想法是检查这些 URL 是否给出有效的 200OK 响应或 404 其他代码 我如何知道我的程序是否不会在他们的服务器上造成高
  • Spring boot 2.0.5.RELEASE和mongo 4.0连接问题

    我正在关注使用 MongoDB 访问数据教程春季网站 https spring io guides gs accessing data mongodb 我将 Mongo DB 服务器版本 4 安装为服务当我使用客户端连接到它时 它的身份验证
  • 帮助我避免 JPA、Hibernate 和 MySQL 的连接超时

    我正在使用 JPA Hibernate 作为提供者 Glassfish 和 MySQL 开发中一切都运行良好 但是当我将应用程序部署到测试服务器并让它运行 大部分空闲 过夜时 我通常会在早上遇到这样的情况 2011 03 09T15 06
  • jpa2 CriteriaBuilder order by “ORDER BY 表达式必须出现在选择列表中”

    我正在写一个查询标准生成器 但无法添加order by子句 因为它随消息一起抛出错误ORDER BY 表达式必须出现在选择列表中这是我的实体 public class A Integer aId ManyToOne JoinColumn n
  • EL 通过 Scriptlet

    在 JSP 中使用 EL 相对于 scriptlet 的优势是什么 EL 被认为是无脚本语言 EL 使 JSP 免受容易出错原始 Java 代码并强制您根据 MVC 思想编写 JSP EL 或像 JSTL 这样的标签库 不可能实现的任何事情
  • 全静态方法和应用单例模式有什么区别?

    我正在创建一个数据库来存储有关我的网站用户的信息 我正在使用 stuts2 因此使用 Java EE 技术 对于数据库 我将创建一个 DBManager 我应该在这里应用单例模式还是将其所有方法设为静态 我将使用这个 DBManager 进
  • 从字符串生成密钥?

    我需要从字符串生成一个密钥 以便我始终可以从同一字符串创建相同的密钥 具体来说是一个Key对象 这样我就可以用它来创建Cipher进而创建SealedObject 这在 Java 中可行吗 我应该考虑什么类 方法组合才能做到这一点 对于 A
  • Android 游戏偶尔出现延迟

    我正在用 Java 制作一个简单的 Android 游戏 我注意到每 20 40 秒就会出现一些烦人的延迟 首先 我认为它们是由垃圾收集器引起的 但当我检查 LogCat 时 我发现游戏滞后时没有垃圾收集 每当游戏开始滞后时 我都会标记日志
  • 如何在 Java 中使用 StringUtils?

    我是 Java 初学者 我想用StringUtils replace但 Eclipse 输出 StringUtils cannot be resolved I tried import java lang 但它不起作用 java lang不
  • org.apache.commons.codec.digest.Md5Crypt.md5Crypt 函数。 linux下出现异常,windows下正常

    我们正在使用commons codec加密密码 使用org apache commons codec digest Md5Crypt md5Crypt功能 在Windows环境下工作正常 但在CentOS上却抛出异常 我们有3台centOS
  • 如何在 JdbcTemplate 中创建 mySQL 存储过程

    背景 为了解决 MySql 中某些语句只允许在存储过程中出现的问题 我尝试在 JdbcTemplate 提交的 sql 中创建 运行然后删除存储过程 一个简单的例子是 这恰好是在 Spring Boot 中 Service public c
  • JFrame Glasspane 也优于 JDialog,但不应该

    我有一个带有 Glasspane 的 JFrame 未装饰 该框架打开一个 JDialog 也未装饰 也有一个 glassPane 并隐藏自身 setVisible false Glasspanes 通过 setGlassPane 设置 对
  • Java 不可变对象 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在学习不变性的概念 据我了解 一旦创建对象 不可变对象就无法更改其值 但我不明白不可变对象的以下用途 They are 自动是线程
  • bufferedinputstream 中标记读取限制有什么用

    我是Java流的新手 我想读取特定的文件内容 然后需要从头开始读取 我创建了一个 BufferedInputStream 但我对 BufferedInputStream mark int markLimit 的文档感到困惑 文档说 publ
  • “___ 中的方法 ___() 是在无法访问的类或接口中定义的”编译错误

    我发现了一个奇怪的编译限制 我无法解释 并且我不明白这个限制的原因 示例1 考虑这些类 In package e1 public class C1 enum E1 A B C public E1 x In package e2 import
  • 更新分页。是否可以?

    他们是否存在一些方法来处理更新分页 例如我有 100 行类型 Id private Integer id Column private boolean flag Column private Date last 一开始它们看起来像 id f
  • 如何在 Log4j2 - JSON 布局中自定义或删除默认属性

    In Spring Boot 2我已配置的应用程序Log4j2 with JsonLayout像下面这样
  • 使用正则表达式匹配阿拉伯文文本

    我试图使用正则表达式仅匹配阿拉伯语文本 但出现异常 这是我的代码 txt matches P Arabic 这是例外情况 线程 main 中的异常 java util regex PatternSyntaxException 索引 9 附近
  • Java 可变 BigInteger 类

    我正在使用 BigIntegers 进行计算 该计算使用一个调用 multiply 大约 1000 亿次的循环 并且从 BigInteger 创建新对象使其非常慢 我希望有人编写或找到了 MutableBigInteger 类 我在 jav

随机推荐

  • Yii2 中模块的自定义 URL 规则

    我一直在四处寻找 但没有找到我需要的东西 基本上 我有一些只有 DefaultController 的小模块和一些带有多个控制器的较大模块 我的小模块规则运行良好 但大模块规则则不行 这是我的规则
  • 如何将数据库连接到 Angular Web 应用程序?

    我想在 Angular Web 应用程序中显示和编辑现有 PostgreSQL 数据库中的数据 我对角度之类的东西完全陌生 我已经下载了pg和express 浏览完这个页面后 https developer mozilla org en U
  • 可以使用 AutoMapper 将一个对象映射到对象列表吗?

    这些是我的课程 public class EventLog public string SystemId get set public string UserId get set public List
  • NHibernate 中的表达式树

    我有一个具有此签名的方法 public static IList
  • 在活动之间保留 Google Play 服务登录

    我认为这很简单 但我一直在兜圈子 试图找出如何让用户保持登录状态Activities 我有一个 主要 和一个 详细信息 Activity 用户登录Google Play Services在 主要 Activity我想在 详细信息 中提交成就
  • 所有视图模型都继承自“BaseViewModel”,我可以在 OnActionExecuting 中设置它吗?

    如果我的所有操作都有一个继承自 BaseViewModel 的模型 是否可以从 OnActionExecuting 方法初始化该模型 目前 在我的所有行动中 我都是这样做的 var model new SomeModel model Use
  • c# WinForms 可以获得 NumericUpDown 文本区域

    是否可以获取 NumericUpDown 控件的文本区域 我正在寻找它的尺寸 以便我可以用面板遮盖它 我不希望用户能够编辑并选择文本 这可能吗 或者还有其他方法可以覆盖文本框中的文本吗 Thanks 您可以通过使用 Label 控件而不是内
  • WinUI 3 打包应用程序未在 AppData 中创建文件夹

    在 WinUI 3 打包应用程序中 我尝试在中创建一个文件夹AppData Local MyApp 在我的应用程序启动中 我正在执行以下操作 public App string apf Environment GetFolderPath E
  • TYPO3 TCA在后端对象保存后执行挂钩

    如果通过后端保存对象 我想操作一些值并执行自定义函数 我通过谷歌搜索发现我必须在我的ext localconfphp GLOBALS TYPO3 CONF VARS SC OPTIONS t3lib class t3lib tcemain
  • fget 是如何工作的?

    我在用海湾合作委员会 Ubuntu 4 8 2 19ubuntu1 4 8 2我正在编写一个非常简单的脚本 以字符串作为输入并使用一些自定义消息打印相同的内容 首先用户输入 T 获取字符串的次数 然后通过以下方式获取输入fgets 我用了t
  • 如何从 Intellij IDEA 部署 tomcat/webapps 文件夹

    我正在通过 Intellij IDEA Tomcat 集成测试 Web 应用程序 基于 Apache Wicket 在那里我注意到 web 应用程序认为它在 tomcat 的 bin 文件夹中运行 另外当我打电话给ServletContex
  • 打开另存为窗口并从单元格填充文件名和文件路径

    我正在尝试打开 另存为 窗口并从单元格填充文件名和文件路径 这是我的代码 它填充文件名并在文件路径中打开 另存为 窗口 但是当我单击 保存 时 文件永远不会显示在应该保存的位置 Sub Save Adds formula to show f
  • 应用内屏幕截图并附加到电子邮件,无需保存到库中

    我想知道如果我想让我的应用程序能够通过按 UI 按钮来截取屏幕截图并立即弹出邮件撰写并通过电子邮件发送屏幕截图而不将其保存到照片库中 我想知道应该使用什么代码 非常感谢 您需要向您的项目添加两个框架 QuartzCore and Messa
  • 从函数返回一个值?

    我正在尝试编写一个函数来分析一些文本和正则表达式模式 例子 import re def foo input pattern text pattern re compile r input patern re I find pattern f
  • 在 php codeigniter 视图中循环

    我得到一个像这样的数组 query data this gt flights gt checkflight form data getting data this gt load gt view payment query sending
  • 从 pandas df 中的列创建二元组

    我在 pandas 数据框中有这个测试表 Leaf category id session id product id 0 111 1 987 3 111 4 987 4 111 1 741 1 222 2 654 2 333 3 321
  • 如何让 Java 检测反向引用,同时尊重字边界?

    我的任务是创建一个正则表达式 用它可以检测多次出现的同一个单词 并将它们全部替换为第一次出现的单词 到目前为止我想出的是 b w b s 1 1 然而 这会检测到例如第二horse in horse horseracing 我只想检测完全匹
  • 如何通过 Java 将二进制数据从 AS3 发送到文件系统?

    我有 AS3 中的 XML 数据 需要对其进行压缩 在我的 Java Google App Engine servlet 上进行验证 然后将其保存到 Google Cloud Storage 中的文件中 稍后该文件将由 AS3 客户端打开并
  • 如何在simulink中创建计数器

    我想计算我的信号变为零的次数 例如 将脉冲信号作为输入 我想要一个变量来计算脉冲变为零的次数 我正在疯狂地思考某事 有人可以帮助我吗 谢谢 figure 1 is a pulse counter model and figure 2 is
  • JFreeChart:自定义 BoxAndWhisker 图表

    我开始使用JFreeChart做一些策划 我希望我的图表如下图所示 我非常接近使用BoxAndWhisker chart 然而 有些事情我仍然想改变 有没有办法去掉盒子 这样我就只有中间线了 如何向条形图添加标签 另外 由于某种原因 y 轴