【问题标题】:JFreeChart - change SeriesStroke of chart lines from solid to dashed in one lineJFreeChart - 将图表线的 SeriesStroke 从实线更改为虚线
【发布时间】:2012-10-25 18:41:39
【问题描述】:

此处接受的答案 (JFreechart(Java) - How to draw lines that is partially dashed lines and partially solid lines?) 帮助我开始了更改图表上的系列笔划线的道路。在单步执行我的代码并观察更改后,我看到我的系列笔画实际上在它应该更改为“dashedStroke”时(在某个日期“dashedAfter”之后),但是当图表被渲染时,整个系列线是虚线.如何让系列线一开始是实线,在设定的日期之后是虚线?

/* 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);

【问题讨论】:

    标签: java charts jfreechart time-series timeserieschart


    【解决方案1】:

    我认为你做对了,如果它不起作用,也许它不可能?我只是在这里猜测,但你可以画 2 条线而不是 1 条线。你的第二条线将从你的第一条线结束的地方开始。如果您想大量更改笔画并且您想根据条件在循环的每次迭代中更改它,那可能会变得混乱,您的代码可能会变得更加复杂。或者只是为每个画一条新线。

    【讨论】:

      【解决方案2】:

      您是否尝试过实现AbstractRenderer#getItemStroke

      在这个例子中,我对系列​​ 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);
      

      虽然此示例使用和 XYSeries 而不是您应该能够根据需要修改它的日期。

      这是完整的例子

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

      【讨论】:

      • +1 关注API advice
      • 这更符合我链接到的示例,并且更接近我开始尝试整个事情的地方。我希望其中一些建议会有所帮助,但我仍然遇到同样的问题,即线条没有从实线变为虚线,而是其中之一。我重新发布了我的代码以反映更改。任何进一步的帮助表示赞赏!
      • @MisterMichaelK 如果您可以一起提供一个自包含示例 (SSCCE),我将为您尝试代码。没有数据就很难看出发生了什么
      • 实际上,我似乎遇到了一些变量问题,这就是为什么它不能正常工作。
      • @GrahamA 我尝试了这个解决方案,但我的数据集始终为空。此外,eclipse 还告诉我数据集总是为空的。我可能做错了什么?仅供参考 - 我正在使用ChartFactory.createTimeSeriesChart。这会是问题吗?
      【解决方案3】:

      我仍然遇到同样的问题,即线条没有从实线变为虚线,而是其中之一。

      setDrawSeriesLineAsPath() 方法“控制是否将每个系列绘制为单个路径。”这排除了动态更改Stroke,因为getItemStroke() 在每个系列中只会被调用一次。

      附录:验证这一点的简单方法是在@GrahamA 的示例中调用setDrawSeriesLineAsPath(),并在调试器中中断drawFirstPassShape()

      【讨论】:

      • 这也是我想要完成的一个关键组成部分。到目前为止,将 setDrawSeriesLineAsPath() 设置为 false 会使我的图表表现正确,因为当我需要时,线会从实线变为虚线。不幸的是,虚线大部分是实心的,除非我的图表大幅上升。我知道这与 sDSLAP() 方法有关,我有很多数据点,并且每个点之间根本没有足够的空间来有效地划线,除非点之间有很大的上升。有没有办法像 getItemStroke() 一样有条件地设置它?
      • NAFAIK,虽然我喜欢ChartPanel#setMouseWheelEnabled(true) 以便于缩放。我想你可以让用户根据需要切换视图,example
      • @MisterMichaelK 如果点靠得很近,为什么不改变颜色而不是线条样式,例如here
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多