2012-11-05 8 views
8

La risposta accettata qui (JFreechart(Java) - How to draw lines that is partially dashed lines and partially solid lines?) mi ha aiutato a iniziare il percorso di modifica delle mie linee di successione sul mio grafico. Dopo aver letto il mio codice e osservato i cambiamenti, vedo che il mio seriesstro in effetti cambia in "dashedStroke" quando è previsto (dopo una certa data "dashedAfter"), ma quando il grafico viene reso l'intera linea della serie viene tratteggiata . Come posso ottenere una linea di serie da disegnare in modo solido all'inizio e tratteggiata dopo una data impostata?JFreeChart - cambia serie di linee del grafico da solido a tratteggiato in una riga

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

risposta

6

Hai provato a implementare AbstractRenderer#getItemStroke?

enter image description here

In questo esempio sto utilizzando una linea tratteggiata per x> 4 per la serie 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); 

Anche se questo esempio sta usando e XYSeries e non date che shold essere in grado di modificare è per te.

Ecco l'esempio completo

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

+1 per seguire la [consigli API] (http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/renderer/AbstractRenderer.html#getItemStroke%28int,%20int%29) – trashgod

+0

Questo è più lungo le linee dell'esempio a cui mi sono collegato, e più vicino a dove ho iniziato a provare tutta questa cosa. Speravo che alcuni di questi suggerimenti aiutassero, ma sto ancora avendo lo stesso problema della linea che non cambia da solido a tratteggiata, ma essendo uno o l'altro. Ho ripubblicato il mio codice per riflettere le modifiche. Ogni ulteriore aiuto è apprezzato! –

+1

@MisterMichaelK se riesci a mettere insieme un esempio autonomo (SSCCE) proverò il codice per te. E 'difficile vedere cosa sta accadendo senza i dati – GrahamA

0

Penso che lo fate a destra e Se non funziona forse non la sua possibile? Sto solo indovinando qui, ma potresti disegnare 2 linee invece di 1. La tua seconda linea inizierà dove finisce la tua prima riga. Ciò potrebbe complicare se si desidera modificare molto il tratto e poiché si desidera modificarlo ogni iterazione del ciclo a seconda di una condizione, il codice probabilmente diventerà molto più complicato. O semplicemente disegnare una nuova linea per ciascuno.

1

Ho ancora lo stesso problema della linea non cambia da solido a tratteggiato, ma essendo uno o l'altro.

Il metodo setDrawSeriesLineAsPath() "controlla se ogni serie è disegnata come un singolo percorso". Ciò preclude la modifica dello Stroke in modo dinamico, poiché getItemStroke() verrà chiamato una sola volta per serie.

Addendum: Un modo semplice per verificare questo è quello di richiamare setDrawSeriesLineAsPath() in @ esempio di GrahamA e rompere in drawFirstPassShape() nel debugger.

+0

Anche questo è un componente chiave di ciò che sto cercando di realizzare. A partire da ora, impostando setDrawSeriesLineAsPath() su false, il mio grafico si comporta correttamente in quanto la linea cambia da solida a tratteggiata quando voglio. Sfortunatamente, il tratteggio è per lo più solido tranne quando il mio grafico aumenta considerevolmente. So che questo è legato al metodo sDSLAP(), ho un sacco di punti dati e semplicemente non c'è abbastanza spazio tra ogni punto per tratteggiare efficacemente le linee a meno che non ci sia un grande aumento tra i punti. C'è un modo per impostare questo condizionatamente così come getItemStroke() era? –

+1

NAFAIK, anche se mi piace 'ChartPanel # setMouseWheelEnabled (true)' per facilitare lo zoom. Suppongo che tu possa consentire all'utente di alternare la visualizzazione come desiderato, per [esempio] (http://stackoverflow.com/a/5522583/230513). – trashgod

+1

@MisterMichaelK se i punti sono vicini, perché non variare il colore piuttosto che il linestyle, esempio [qui] (http://stackoverflow.com/questions/11962836/jfreechart-different-colors-in-different-regions-for- the-same-dataseries/11965997 # 11.965.997). – GrahamA

Problemi correlati