JFreeChart - 将图表线的 SeriesStroke 从实线更改为单线虚线

2023-11-26

此处接受的答案(JFreechart(Java) - 如何绘制部分虚线和部分实线的线?)帮助我开始改变图表上的系列划线。在单步执行我的代码并观察更改后,我发现我的系列笔画实际上在应该的时候(在某个日期“dashedAfter”之后)更改为“dashedStroke”,但是当渲染图表时,整个系列线都是虚线。如何让系列线首先绘制为实线,然后在设定的日期后绘制为虚线?

/* series line modifications */
final Number dashedAfter = timeNowDate.getTime();

XYLineAndShapeRenderer render = new XYLineAndShapeRenderer() {
  Stroke regularStroke = new BasicStroke();
  Stroke dashedStroke = new BasicStroke(
                            1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
                            1.0f, new float[] {10.0f, 6.0f}, 0.0f );
  @Override
  public Stroke getItemStroke(int row, int column) {
    Number xVal = cd.getXValue(row, column);
    if (xVal.doubleValue() > dashedAfter.doubleValue()) { 
      return dashedStroke; 
    } else { 
      return regularStroke; 
    }
  }
};
render.setBaseShapesVisible(false);
render.setBaseShapesFilled(true);
render.setDrawSeriesLineAsPath(true);
plot.setRenderer(render);

您是否尝试过实施AbstractRenderer#getItemStroke?

enter image description here

在此示例中,我使用虚线表示系列 2 的 x > 4:

XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(){
    Stroke soild = new BasicStroke(2.0f);
    Stroke dashed =  new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] {10.0f}, 0.0f);
    @Override
    public Stroke getItemStroke(int row, int column) {
if (row == 2){
  double x = dataset.getXValue(row, column);
  if ( x > 4){
    return dashed;
  } else {
    return soild;
  } 
} else
  return super.getItemStroke(row, column);
    }
  };
  renderer.setBaseShapesVisible(true);
  renderer.setBaseShapesFilled(true);
  renderer.setBaseStroke(new BasicStroke(3));
  plot.setRenderer(renderer);

虽然这个例子使用的是 andXYSeries而不是您应该能够根据需要修改它的日期。

这是完整的例子

import java.awt.BasicStroke;
import java.awt.Stroke;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class LineChartDemo2 extends ApplicationFrame {

    public LineChartDemo2(String title) {
        super(title);
        JPanel chartPanel = createDemoPanel();
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);
    }

    private static JFreeChart createChart(final XYDataset dataset) {

        JFreeChart chart = ChartFactory.createXYLineChart(
            "Line Chart Demo: XYLineAndShapeRenderer",     
            "X",                     
            "Y",                     
            dataset,              
            PlotOrientation.VERTICAL,
            false,                     
            false,                 
            false             
        );

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setDomainPannable(true);
        plot.setRangePannable(true);

        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(){
            Stroke soild = new BasicStroke(2.0f);
            Stroke dashed =  new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] {10.0f}, 0.0f);
            @Override
            public Stroke getItemStroke(int row, int column) {
                if (row == 2){
                    double x = dataset.getXValue(row, column);
                    if ( x > 4){
                        return dashed;
                    } else {
                        return soild;
                    } 
                } else
                    return super.getItemStroke(row, column);
            }
        };

        renderer.setBaseShapesVisible(true);
        renderer.setBaseShapesFilled(true);
        renderer.setBaseStroke(new BasicStroke(3));
        plot.setRenderer(renderer);
        return chart;
    }

    public static JPanel createDemoPanel() {
        JFreeChart chart = createChart(createDataset());
        ChartPanel panel = new ChartPanel(chart);
        panel.setMouseWheelEnabled(true);
        return panel;
    }

    public static void main(String[] args) {
        LineChartDemo2 demo = new LineChartDemo2(
                "JFreeChart");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }

    private static XYDataset createDataset() {

        XYSeries series1 = new XYSeries("First");
        series1.add(1.0, 1.0);
        series1.add(2.0, 4.0);
        series1.add(3.0, 3.0);
        series1.add(4.0, 5.0);
        series1.add(5.0, 5.0);
        series1.add(6.0, 7.0);
        series1.add(7.0, 7.0);
        series1.add(8.0, 8.0);

        XYSeries series2 = new XYSeries("Second");
        series2.add(1.0, 5.0);
        series2.add(2.0, 7.0);
        series2.add(3.0, 6.0);
        series2.add(4.0, 8.0);
        series2.add(5.0, 4.0);
        series2.add(6.0, 4.0);
        series2.add(7.0, 2.0);
        series2.add(8.0, 1.0);

        XYSeries series3 = new XYSeries("Third");
        series3.add(3.0, 4.0);
        series3.add(4.0, 3.0);
        series3.add(5.0, 2.0);
        series3.add(6.0, 3.0);
        series3.add(7.0, 6.0);
        series3.add(8.0, 3.0);
        series3.add(9.0, 4.0);
        series3.add(10.0, 3.0);

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series1);
        dataset.addSeries(series2);
        dataset.addSeries(series3);

        return dataset;

    }


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

JFreeChart - 将图表线的 SeriesStroke 从实线更改为单线虚线 的相关文章

随机推荐

  • Java 中原始整数类型的行为不一致

    有人可以向我解释一下 就像我五岁一样 为什么我在 Java 中表示整数的四种基本类型中的两种会得到不同的行为 AFAIK 所有四个都是有符号的 并且它们都使用最高有效位作为符号位 那么为什么 byte 和 Short 表现正常 而 int
  • 显示进度条,显示表单提交的进度

    这个问题还没有完全解答 欢迎大家踊跃留言 我正在尝试显示一个简单的progress bar提交大表格时 该表单包含十几个字段 以及一些文件上传字段 用户可以在其中选择图片 然后 当他点击Create按钮 提交带有数据和图片的表单 并在数据库
  • 使用 Fluent nHibernate 和 Ninject 实现多租户。每个租户一个数据库

    我正在构建一个多租户 Web 应用程序 出于安全考虑 我们需要为每个租户拥有一个数据库实例 所以我有一个用于身份验证的 MainDB 和许多用于应用程序数据的 ClientDB 我正在使用 Asp net MVC 与 Ninject 和 F
  • 使用 PDFBox 添加页码

    如何向使用 PDFBox 生成的文档中的页面添加页码 谁能告诉我如何在合并不同的 PDF 后向文档添加页码 我正在使用 Java 中的 PDFBox 库 这是我的代码 它运行良好 但我需要添加页码 PDFMergerUtility ut n
  • iOS StoreKit - 何时调用 - (void)restoreCompletedTransactions?

    我的应用程序中有很多一次性购买的 IAP 用户可以购买它们 我的问题是 我正在与 Flurry 集成来跟踪实际购买情况 而不是仅仅恢复购买情况 但我的SKPaymentTransaction s transactionState总是回来作为
  • AttributeError:“列表”对象没有属性“点击” - Selenium Webdriver

    我正在尝试使用 python 在 Selenium webdriver 中使用 click 命令 但我收到以下错误 有人能帮我吗 Traceback most recent call last File C Users vikram wor
  • 在android中创建自定义工具栏

    我正在尝试在 android 中创建一个自定义扩展工具栏 并在工具栏中编辑文本 我想要实现的布局看起来像这样 我编写的实现代码是这样的
  • 无法获取当前线程的事务同步会话

    我在从 xml 转换为 Java Config 的 Spring4 Hibernate4 项目中遇到以下异常 org hibernate HibernateException Could not obtain transaction syn
  • threading.local() 是在 Google AppEngine 中存储单个请求的变量的安全方法吗?

    我有一个 google appengine 应用程序 我只想为该请求设置一个全局变量 我可以这样做吗 在request vars py中 request vars py global vars threading local 在另一个 py
  • 在 Fortran 中打开二进制文件:状态、表单、访问

    我使用 Fortran 已有多年 但文件 I O 对我来说仍然很模糊 我的理解status form access recl是有限的 因为我在研究生院需要某些用例 我知道 Fortran 二进制文件在文件顶部有描述文件大小的额外信息 但这对
  • 无法使用response.sendRedirect进行重定向

    我在 google 上搜索了好几个小时 了解如何在 jsp 或 servlet 中进行重定向 然而 当我尝试应用它时 它不起作用 我在jsp页面内的代码 我从调试中知道 regexp 有效 并且如果有任何时候 articleId 不是数字
  • Android 布局参数仅更改宽度和高度

    我知道如何使用设置视图的宽度和高度LayoutParams通过执行以下操作 android view ViewGroup LayoutParams params button getLayoutParams params width hei
  • 可以运行的最大 Swing 工作线程数是多少

    可以运行的 Swing Worker 线程数是否有上限 或者是内存支持的上限 这也可以在某处配置吗 A SwingWorker本身不是线程 而是将在线程中执行的任务 通常 您会使用ExecutorService执行实例SwingWorker
  • C# 将一个列表拆分为多个列表

    我有一个发送到队列的字符串列表 我需要拆分列表 以便最终得到一个列表列表 其中每个列表包含最大 用户定义 数量的字符串 例如 如果我有一个包含以下 A B C D E F G H I 的列表 并且列表的最大大小为 4 我希望最终得到一个列表
  • 如何在Windows上安装tesserocr?

    我下载了 tesseract OCR 的可执行文件并安装了它 另一方面 我还从以下位置下载了 leptonica 的 zip 文件 http www leptonica com download html 它包括两个目录 即lib and
  • 在Python中应用时变过滤器

    我正在尝试使用 Python 将具有时变截止频率的带通滤波器应用于信号 我当前使用的例程将信号划分为等长的时间段 然后对于每个段 我应用具有特定时间参数的滤波器 然后将信号合并在一起 这些参数基于预先存在的估计 我似乎遇到的问题是 应用过滤
  • MySQL:连续月份的记录计数

    我已经四处寻找这个 但所有类似的问题和答案都不同 无法工作 我有一个包含以下字段的表 人 事 purdate 当一个人购买每一件新东西时 就会输入一个新记录 我想计算一个人连续几个月购买了任何东西 thing01 或 thing02 没关系
  • 在 R 中复制矩阵的行

    假设我有一个矩阵m和一个正整数向量v 我想做的是得到一个新的矩阵m new和每一行m say m i 被复制v i 次在m new 例如 m matrix 1 6 nrow 3 1 2 1 1 4 2 2 5 3 3 6 v c 3 1 2
  • 为什么 GCC 不在编译时评估 constexpr?

    举个例子 class something public static constexpr int seconds int hour int min int sec return hour 3600 min 60 sec then print
  • JFreeChart - 将图表线的 SeriesStroke 从实线更改为单线虚线

    此处接受的答案 JFreechart Java 如何绘制部分虚线和部分实线的线 帮助我开始改变图表上的系列划线 在单步执行我的代码并观察更改后 我发现我的系列笔画实际上在应该的时候 在某个日期 dashedAfter 之后 更改为 dash