2012-11-05 23 views
8

ここで受け入れられる答え(JFreechart(Java) - How to draw lines that is partially dashed lines and partially solid lines?)は、私のグラフ上で私のシリーズストロークラインを変更する道を始めるのに役立ちました。私のコードをステップ実行して変更を見ると、私のシリーズストロークは実際には "dashedStroke"に変更されます(特定の日付 "dashedAfter"の後)、チャートがレンダリングされるとシリーズライン全体が破線で示されます。どのようにして、最初にシリーズ線を描画し、設定された日付の後に破線を描くことができますか?JFreeChart - グラフ線の実線から実線へ1行に変更

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

答えて

6

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

この例では、使用してXYSeriesはなく、日付されているが、変更することができSHOLDそれはあなたのために必要です。ここで

は完全な例

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 [APIアドバイス](http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/renderer/AbstractRenderer.html#getItemStroke%28int,%20int%29) – trashgod

+0

これは私がリンクしている例の行に沿っており、この全体を試し始めたところに近い。私はこれらの提案のいくつかが助けになることを期待していましたが、私はまだ線の同じ問題を固体から破線に変えずに、どちらか一方に変えています。変更を反映するためにコードを再掲載しました。それ以上の助けをいただければ幸いです! –

+1

@MisterMichaelK自己完結型の例(SSCCE)をまとめることができるなら、コードを試してみます。データなしで何が見えないのか分かりません。 – GrahamA

0

私はあなたが正しいことをすると思いますし、それができないのかもしれないと思いますか?今ここで推測していますが、1ではなく2行を描くことができます。2行目は最初の行が終了するところから始まります。ストロークを変更したい場合は面倒なことがあり、条件に応じてループの繰り返しを変更したいので、コードはもっと複雑になるでしょう。あるいは、それぞれに新しい行を引くだけです。

1

である私はまだ破線に固体から変化していない行の同じ問題を抱えて、1つまたは他のものです。

setDrawSeriesLineAsPath()メソッドは、 "各シリーズが単一のパスとして描画されるかどうかを制御します。"これにより、getItemStroke()はシリーズごとに1回だけ呼び出されるため、Strokeを動的に変更することはできません。

補足:これを確認する簡単な方法は、@ GrahamAの例でsetDrawSeriesLineAsPath()を呼び出し、デバッガでdrawFirstPassShape()を中断する方法です。

+0

これは私が達成しようとしていることの鍵となる要素です。現在、setDrawSeriesLineAsPath()をfalseに設定すると、必要なときに線が実線から破線に変わるという点で、私のチャートが正しく動作します。残念なことに、破線は、私のグラフがかなり上昇した場合を除いてほとんど堅実です。私はこれがsDSLAP()メソッドに関連していることを知っています。私は多くのデータポイントを持っており、ポイント間に大きな上昇がなければ、 getItemStroke()のようにこれを条件付きで設定する方法はありますか? –

+1

NAFAIK、私は簡単なズームのために 'ChartPanel#setMouseWheelEnabled(true)'が好きです。私はあなたが[example](http://stackoverflow.com/a/5522583/230513)のためにあなたが望むようにビューをトグルさせることができると思います。 – trashgod

+1

@MisterMichaelKポイントが近い場合どうしてなぜlinestyleではなく色を変えないのですか?[ここ](http://stackoverflow.com/questions/11962836/jfreechart-different-colors-in-different-regions-for-同じ - dataseries/11965997#11965997)。 – GrahamA

関連する問題