2012-11-05 61 views
8

這裏接受的答案(JFreechart(Java) - How to draw lines that is partially dashed lines and partially solid lines?)幫助我開始更改我的圖表中的串行線條。在逐步完成我的代碼並觀察這些變化後,我發現當它應該(在某個日期「dashedAfter」之後)時,我的seriesstroke事實上改變爲「dashedStroke」,但是當圖表渲染時,整個系列行是虛線的。我怎樣才能讓一系列的線條在一個固定的日期之後變得堅實並且破滅?JFreeChart - 將圖表線條中的SeriesStroke從一條直線變爲一條虛線

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

在這個例子中,我使用X> 4的虛線爲系列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); 

雖然這個例子是使用,你應和能夠修改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; 

    } 


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

我認爲你做對了,如果它沒有工作,也許它不可能?我只是猜測在這裏,但你可以畫2行而不是1.你的第二行將開始你的第一行結束。如果你想改變筆畫,並且想要根據條件改變它的每一次迭代,你的代碼可能會變得更加複雜。或者爲每個都畫一條新線。

1

我仍然有不改變從固體到虛線行的同樣的問題,但作爲一個或另一個。

setDrawSeriesLineAsPath()方法「控制每個系列是否繪製爲單一路徑。」這排除了Stroke動態更改,因爲getItemStroke()將被稱爲每個系列一次。

附錄:一個簡單的方法來驗證這是在@ GrahamA的例子中調用setDrawSeriesLineAsPath(),並在調試器中打破drawFirstPassShape()

+0

這也是我試圖完成的關鍵組成部分。到目前爲止,將setDrawSeriesLineAsPath()設置爲false會使我的圖表正常工作,因爲當我需要時,線條從實體變爲虛線。不幸的是,除非我的圖表大幅上漲,否則虛線大部分是穩定的。我知道這與sDSLAP()方法有關,我有很多數據點,並且在每個點之間沒有足夠的空間來有效地劃線,除非點之間有大的上升。有沒有辦法像getItemStroke()那樣有條件地設置它? –

+1

NAFAIK,雖然我喜歡'ChartPanel#setMouseWheelEnabled(true)'以便於縮放。我想你可以讓用戶根據需要切換視圖,例如(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