2012-01-11 21 views
0

私はJFreeChartを使用してグラフを描くことができるアプリケーションのメンテナンスを担当しています。 アプリケーションはEclipse-RCPおよびSWTで作成され、ChartCompositeを使用してチャートを表示します。JfreeChartは表示される凡例項目の数を制限します

ChartCompositeが部分的に選択に応じて、コンテキストメニューをカスタマイズするためにオーバーライドされています

@Override 
    public void createPartControl(Composite parent) { 
    super.createPartControl(parent); 

    chart = createChart(timeSeriesDataset); 

    chartComposite = new MyChartComposite(this, parent, SWT.NONE, chart, true); 
    chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); 

    selectionProvider = new GenericObjectSelectionProvider(); 
    getSite().setSelectionProvider(selectionProvider); 

    // add information to the status line: 
    selectionProvider.addSelectionChangedListener(statusLineListener); 

    addDropSupport();// add D'n D support for dropping TimeSeries 

} 


protected JFreeChart createChart(TimeSeriesCollection ptimeSeriesDataset) { 

     JFreeChart vChart = ChartFactory.createTimeSeriesChart(null, "time", "values", ptimeSeriesDataset, true, 
       false, false); 
     vChart.setBackgroundPaint(Color.white); 

     XYPlot plot = vChart.getXYPlot(); 
     plot.setBackgroundPaint(Color.lightGray); 
     plot.setDomainGridlinePaint(Color.white); 
     plot.setRangeGridlinePaint(Color.white); 
     // plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0)); 
     plot.setDomainCrosshairVisible(true); 
     plot.setRangeCrosshairVisible(true); 

     plot.setRenderer(new /*OptimisedXYLineAndShapeRenderer()*/ StandardXYItemRendererFast()); 
     XYItemRenderer renderer = plot.getRenderer(); 
     renderer.setBaseToolTipGenerator(new MyXYSeriesToolTipGenerator()); 
     renderer.setBaseItemLabelGenerator(new MyXYSeriesItemLabelGenerator()); 
     renderer.setLegendItemLabelGenerator(new MyXYSeriesLegendItemLabelGenerator()); 
     if (renderer instanceof XYLineAndShapeRenderer) { 
      XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) renderer; 
      r.setBaseShapesVisible(false); 
      r.setBaseShapesFilled(true); 
     } 

     SimpleDateFormat dateFormat = getDateFormatAbscissa(); 
     if (dateFormat != null){ 
      DateAxis axis = (DateAxis) plot.getDomainAxis(); 
      axis.setDateFormatOverride(dateFormat); 
     } 

     return vChart; 
    } 

私の問題は、あまりにも多くの変数は、チャート(TimeSeriesChart)に追加されたときにキャプションがあまりにも多くを取ることです

ChartComposite with 2 series

ChartComposite many series

:スペースとグラフが視界から消えます

私は、ChartCompositeでスクロールするScrollCompositeを作成しようとしましたが、結果は少し良くなりました。しかし、それは唯一のグラフが再び消える前に、キャプションに複数の項目を追加することが可能になる:

ScrolledComposite scrollableChart = new ScrolledComposite(parent, SWT.BORDER|SWT.V_SCROLL); 

chartComposite = new MyChartComposite(this, scrollableChart, SWT.NONE, chart, true); 
//chartComposite = new MyChartComposite(this, parent, SWT.NONE, chart, true); 
//chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); 

scrollableChart.setContent(chartComposite); 
scrollableChart.setExpandVertical(true); 
scrollableChart.setExpandHorizontal(true); 
scrollableChart.setMinSize(ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH, ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH); 

私の質問は:多くのシリーズがプロットされたときにグラフを維持するためにChartCompositeに本当のスクロールバーを提供する方法グラフに?

答えて

2

SWTのXYSeriesにスライダを同期させるには、FormDataを使用してChartComositeとSliderオブジェクトを使用することができました。スライダを移動するたびに、私はそのイベントをキャプチャし、私のニーズに合わせてチャートを自分自身で更新します。

私のユースケースはあなたと異なる場合がありますが、私の答えはhereです。あなたがその答えで説明した私の実装に関する質問がある場合は

、いくつかの回失敗した詳細

+0

ありがとう:だからここ

はコードです。 – zeropouet

1

のために気軽に、私はチャート上に示されLegendItemの数を制限することを決めました。

LegendTitleに表示する凡例の項目を変更するには、スライダを使用しました。最も難しいのは、スライダを使用するときに新しいLegendTitleを再作成することでした。私のソリューションが最適かエレガントかは分かりませんが、少なくともそれは機能しています。

Result

私はLegendTitleをリフレッシュし、スライダーの値を設定するために、一連の作成(ChartChangeEventType.DATASET_UPDATED)を聞くために必要なこれを可能にします。私はちょうど私が私のニーズにソリューションを適応しようと、数時間前にあなたのポストを見つけ

public class MyExampleChartComposite extends ChartComposite { 
    // snip 
    /** 
    * A slider to choose the legend items to display 
    */ 
    private Slider legendSlider; 
    /** 
    * Number of legend items to display on the chart 
    */ 
    private final static int NUMBER_OF_LEGENDITEMS_TO_DISPLAY = 10; 

    private void createPartControl(Composite parent, int style) { 
     JFreeChart chart = createChart(); 
     setChart(chart); 
     legendSlider = new Slider(parent, SWT.NONE|SWT.H_SCROLL); 
     legendSlider.addSelectionListener(new SelectionListener() { 
      @Override 
      public void widgetSelected(SelectionEvent arg0) { 
         refreshLegend(); 
      } 
     }); 

    private JFreeChart createChart() { 
     chart.addChangeListener(new ChartChangeListener() {  
      @Override 
      public void chartChanged(ChartChangeEvent e) { 
        if (e.getType().equals(ChartChangeEventType.DATASET_UPDATED)) { 
         refreshLegend(); 
        } 
      } 
     }); 
    } 

    /** 
    * Refresh the the LegendItems and the slider, 
    * according to slider selection. 
    */ 
    public void refreshLegend() { 
     // Display LegendItems according to the selection 
     // display the 10 nearest legend item (current selected element included) 
     int begin = legendSlider.getSelection() - (NUMBER_OF_LEGENDITEMS_TO_DISPLAY/2); 
     int end = legendSlider.getSelection() + (NUMBER_OF_LEGENDITEMS_TO_DISPLAY/2 -1); 
     int seriesEndIndex = Math.max(getSeriesCount()-1, 0); 
     // if begin is less than 0 
     // set it to 0, and increase end to display 10 items 
     if (begin < 0) { 
      begin = 0; 
      end = NUMBER_OF_LEGENDITEMS_TO_DISPLAY - 1; 
     } 
     // if end is greater than the number of series plotted 
     // set it to the max possible value and increase begin to 
     // display 10 items 
     if (end > seriesEndIndex) { 
      end = seriesEndIndex; 
      begin = seriesEndIndex - (NUMBER_OF_LEGENDITEMS_TO_DISPLAY - 1); 
     } 
     end = Math.min(seriesEndIndex, end); 
     begin = Math.max(begin, 0); 
     // Refresh only if begin != end 
     if (end != begin) { 
      refreshLegendItems(begin, end); 
      refreshLegendSlider(); 
     } else { 
      // in this case no more series are plotted on the chart 
      // clear legend 
      getChart().clearSubtitles(); 
     } 
    } 
    /** 
    * Refresh the LegendTitle. 
    * Display only LegendItems between beginIndex and toIndex, 
    * to preserve space for the chart. 
    * @param beginIndex index of the {@link LegendItemCollection} used as the beginning of the new {@link LegendTitle} 
    * @param endIndex index of the {@link LegendItemCollection} used as the end of the new {@link LegendTitle} 
    */ 
    private void refreshLegendItems(int beginIndex, int endIndex) { 
     // Last 10 items 
     final LegendItemCollection result = new LegendItemCollection(); 
     // get the renderer to retrieve legend items 
     XYPlot plot = getChart().getXYPlot(); 
     XYItemRenderer renderer = plot.getRenderer(); 
     // Number of series displayed on the chart 
     // Construct the legend 
     for (int i = beginIndex; i <= endIndex; i++) { 
      LegendItem item = renderer.getLegendItem(0, i); 
      result.add(item); 
     } 
     // Because the only way to create a new LegendTitle is to 
     // create a LegendItemSource first 
     LegendItemSource source = new LegendItemSource() { 
      LegendItemCollection lic = new LegendItemCollection(); 
      {lic.addAll(result);} 
      public LegendItemCollection getLegendItems() { 
       return lic; 
      } 
     }; 
     // clear previous legend title 
     getChart().clearSubtitles(); 
     // Create the new LegendTitle and set its position 
     LegendTitle legend = new LegendTitle(source); 
     legend.setHorizontalAlignment(HorizontalAlignment.CENTER); 
     legend.setVerticalAlignment(VerticalAlignment.CENTER); 
     legend.setPosition(RectangleEdge.BOTTOM); 
     legend.setBorder(1.0, 1.0, 1.0, 1.0); 
     legend.setVisible(true); 
     // Add the LegendTitle to the graph 
     getChart().addLegend(legend); 
    } 

    /** 
    * Set values of the slider according to the number of series 
    * plotted on the graph 
    */ 
    private void refreshLegendSlider() { 
     int max = getSeriesCount() -1; 
     int selection = Math.min(legendSlider.getSelection(), max); 
     legendSlider.setValues(selection, 0, max, 1, 1, 1); 
    } 
} 
+0

私の問題はあなたとかなり異なっていましたが、私はこれらのJFreeクラス(特に 'LegendTitle'と' LegendItemSource')に関してあなたが共有した洞察を使うことができました。どうもありがとう! –

関連する問題