English 中文(简体)
JfreeChart限制展示的晚间物品数量
原标题:JfreeChart limit the number of legend items displayed

I m in charge of maintaining an application which can draw graphs using JFreeChart. The application is written in Eclipse-RCP and SWT and use a ChartComposite to display the charts.

图CComposite被部分压倒,以便根据选择情况定制:

@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;
    }

我的问题是,如果在图表中添加太多的变数(时间线图),则封顶占用了太多的空间,图象从以下观点消失:

https://i.stack.imgur.com/tw9v5.png”rel=“nofollow”>ChartComposite with 2 series

图Composite many series

I tried to create a ScrollComposite to scroll in the ChartComposite and the result is a little better; but it only makes it possible to add more items in the caption before the graph disappears again:

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

我的问题是:如何为制图委员会提供一个真正的滚动屏障,以便在图表中列举许多系列时保持图表?

最佳回答
问题回答

经过几次尝试,我决定限制图表所示<代码>LegendItem。

更改序号,在<代码>上显示 图二 我使用了梯子。 最困难的方面是在使用梯子时重新计算新图象;我不敢肯定我的解决方法是最佳的,或者说是明智的,但至少是行之有效的。

“Result”/

为了做到这一点,我需要聆听一系列创作(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);
    }
}




相关问题
how to detect Android ListView Scrolling stopped?

I m trying to do something after scrolling stopped.So, I tried using OnScrollListener#onScrollStateChanged(SCROLL_STATE_IDLE) to detect when the scrolling stopped(either TOUCH_SCROLL or FLING)(at 1.5 ...

jQuery - ScrollTo and Serial Scroll not working together

I have tested the scrollTo() plugin, but I need a way to stop the scrolling animation, so I am looking at serialScroll(). Here is what I used with scrollTo: $( #scroller ).scrollTo( 1000px , 3000); ...

Scrolling to the bottom of a div

As part of an ajax chat room (using prototype framework) I am working on I scroll the user to the bottom each time a message is added using the below js. However if the user has scrolled up and the ...

Displaying news with javascript

I keep coming up against this issue. Displaying news on a website. And I d like to come up with a solution to use like a template, something I can just drop on a site easily. The solution I keep ...

UITextview content moves up when textview is selected

I am pretty new to this iPhone dev thing but so far I have built a pretty good app but I have stumbled into this problem that for the life of me I cannot seem to solve. Basically the app is a chat ...

热门标签