JFreeChart - change SeriesStroke of chart lines from solid to dashed in one line

前端 未结 3 998
生来不讨喜
生来不讨喜 2021-01-12 05:36

The answer accepted here (JFreechart(Java) - How to draw lines that is partially dashed lines and partially solid lines?) helped me start down the path of changing my series

相关标签:
3条回答
  • 2021-01-12 06:19

    Have you tried implementing AbstractRenderer#getItemStroke?

    enter image description here

    In this example I'm using a dashed line for x > 4 for series 2:

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

    Although this example is using and XYSeries and not dates you shold be able to modify it for you needs.

    Here is the full example

    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;
    
        }
    
    
    }
    
    0 讨论(0)
  • 2021-01-12 06:25

    I'm still having the same problem of the line not changing from solid to dashed, but being one or the other.

    The setDrawSeriesLineAsPath() method "controls whether or not each series is drawn as a single path." This precludes changing the Stroke dynamically, as getItemStroke() will be called only once per series.

    Addendum: An easy way to verify this is to invoke setDrawSeriesLineAsPath() in @GrahamA's example and break in drawFirstPassShape() in the debugger.

    0 讨论(0)
  • 2021-01-12 06:26

    I think that you do it right and if it doesnt work maybe its not possible? Im just guessing here but you could draw 2 lines instead of 1. Your second line would begin where your first line ends. That could get messy if you want to change the stroke alot and as you want to change it every iteration of your loop depending on a condition, your code will probably get alot more complicated. Or just draw a new line for each.

    0 讨论(0)
提交回复
热议问题