JFreeChart - 带有2个图例的颜色问题

时间:2011-04-27 07:28:03

标签: java colors jfreechart legend

我尝试在我的图表中创建一个自定义图例但是当我显示一个或两个图例时会发生奇怪的事情。当我显示2个传说(旧的和新的)时,一切都很好,颜色在图例和图表中都得到了尊重。但是,当我只想显示新图例时,图例中的颜色会受到尊重,但图表中的颜色不再受到尊重。

这是我的问题的一个例子: 您必须评论并撤消一行以查看问题(请参阅注释)

package org.jfree.chart.demo;

import java.awt.Color;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JPanel;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.LegendItemSource;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RefineryUtilities;

public class Sample extends ApplicationFrame {

/**
 * 
 */
private static final long serialVersionUID = 1L;

private static ArrayList<Date> A;
private static ArrayList<Date> B;
private static ArrayList<Date> C;
private static Calendar t0;

public Sample(String paramString) {
    super(paramString);
    t0 = Calendar.getInstance();
    t0.set(2010, Calendar.JANUARY, 1);
    A = new ArrayList<Date>();
    B = new ArrayList<Date>();
    C = new ArrayList<Date>();
    JPanel localJPanel = createDemoPanel();
    setContentPane(localJPanel);

}

private static XYPlot createSubplot1(XYDataset paramXYDataset) {

    // With Dots
    XYLineAndShapeRenderer localXYLineAndShapeRenderer = new XYLineAndShapeRenderer();
    localXYLineAndShapeRenderer.setBaseLinesVisible(false);
    localXYLineAndShapeRenderer.setUseFillPaint(false);
    localXYLineAndShapeRenderer.setBaseFillPaint(Color.white);
    localXYLineAndShapeRenderer.setBaseShape(new Ellipse2D.Double(-4.0D,
            -4.0D, 8.0D, 8.0D));
    localXYLineAndShapeRenderer.setAutoPopulateSeriesShape(false);

    NumberAxis localNumberAxis = new NumberAxis("TEST");
    localNumberAxis.setVisible(false);
    localNumberAxis.setRange(0.5, 1.5);

    XYPlot localXYPlot = new XYPlot(paramXYDataset, new DateAxis("Time"),
            localNumberAxis, localXYLineAndShapeRenderer);

    return localXYPlot;

}

private static JFreeChart createChart() {
    CombinedDomainXYPlot localCombinedDomainXYPlot = new CombinedDomainXYPlot(
            new DateAxis("Time"));

    localCombinedDomainXYPlot.add(createSubplot1(createDataset1()), 1);

    JFreeChart localJFreeChart = new JFreeChart("Sample",
            localCombinedDomainXYPlot);
    localJFreeChart.getLegend().setPosition(RectangleEdge.TOP);
    localJFreeChart.getLegend().getItemContainer().getBlocks();

    localJFreeChart.setBackgroundPaint(Color.white);

    LegendItemCollection legendItemsOld = localCombinedDomainXYPlot
            .getLegendItems();
    final LegendItemCollection legendItemsNew = new LegendItemCollection();

    for (int i = 0; i < legendItemsOld.getItemCount(); i++) {
        legendItemsNew.add(legendItemsOld.get(i));
    }
    LegendItemSource source = new LegendItemSource() {
        LegendItemCollection lic = new LegendItemCollection();
        {
            lic.addAll(legendItemsNew);
        }

        public LegendItemCollection getLegendItems() {
            return lic;
        }
    };
    localJFreeChart.addLegend(new LegendTitle(source));

    ChartUtilities.applyCurrentTheme(localJFreeChart);

    ////////////////////////////////////////////////////////////////////////
    /**
     * If you comment the following line, two legends are displayed and the
     * colors in the graph are respected (yellow, red, blue, red, green)
     * However, when you decomment the line, only the new legend is
     * displayed. The legend is correct but the colors in the graph are not
     * respected anymore (red, yellow, green, yellow, blue)
     */
    /////////////////////////////////////////////////////////////////////////
    // localJFreeChart.getLegend().setVisible(false);



    return localJFreeChart;
}

public static JPanel createDemoPanel() {
    return new ChartPanel(createChart());
}

private static XYDataset createDataset1() {
    final Calendar out1 = Calendar.getInstance();
    out1.set(2009, Calendar.JANUARY, 1);

    final Calendar out2 = Calendar.getInstance();
    out2.set(2010, Calendar.JANUARY, 3);

    final Calendar end = Calendar.getInstance();
    end.set(2012, Calendar.SEPTEMBER, 30);

    Date date1 = date(t0, 0);
    TimeSeries s1 = new TimeSeries("RED");

    int i = 0;

    TimeSeries s4 = new TimeSeries("YELLOW");
    TimeSeries s2 = new TimeSeries("BLUE");
    TimeSeries s3 = new TimeSeries("GREEN");

    RegularTimePeriod rtpt0 = new FixedMillisecond(t0.getTime());
    TimeSeriesDataItem t = new TimeSeriesDataItem(rtpt0, 1);
    s4.add(t);
    i++;
    int interval = 57;
    date1 = date(t0, 0 + interval * i);
    Calendar d1;

    while (date1.before(date(end, 0))) {

        while (date1.before(date(end, 0)) && i < 8) {
            RegularTimePeriod rtp = new FixedMillisecond(date1.getTime());
            A.add(date1);
            t = new TimeSeriesDataItem(rtp, 1);
            s1.add(t);

            d1 = Calendar.getInstance();
            d1.setTimeInMillis(date1.getTime());
            date1 = date(d1, 0 + interval);
            i++;

        }

        if (date1.before(date(end, 0))) {
            RegularTimePeriod rtp = new FixedMillisecond(date1.getTime());
            B.add(date1);
            t = new TimeSeriesDataItem(rtp, 1);
            s2.add(t);
            d1 = Calendar.getInstance();
            d1.setTimeInMillis(date1.getTime());
            date1 = date(d1, 0 + interval);
        }
        d1 = Calendar.getInstance();
        d1.setTimeInMillis(date1.getTime());
        date1 = date(d1, 14);
        i = 1;
        while (date1.before(date(end, 0)) && i < 8) {
            RegularTimePeriod rtp = new FixedMillisecond(date1.getTime());
            A.add(date1);
            t = new TimeSeriesDataItem(rtp, 1);
            s1.add(t);
            d1 = Calendar.getInstance();
            d1.setTimeInMillis(date1.getTime());
            date1 = date(d1, 0 + interval);
            i++;

        }
        i = 0;
        if (date1.before(date(end, 0))) {
            RegularTimePeriod rtp = new FixedMillisecond(date1.getTime());
            C.add(date1);
            t = new TimeSeriesDataItem(rtp, 1);
            s3.add(t);
            d1 = Calendar.getInstance();
            d1.setTimeInMillis(date1.getTime());
            date1 = date(d1, 0 + interval);
        }
        d1 = Calendar.getInstance();
        d1.setTimeInMillis(date1.getTime());
        date1 = date(d1, 61);

    }

    TimeSeriesCollection dataset = new TimeSeriesCollection();

    dataset.addSeries(s1);
    dataset.addSeries(s2);
    dataset.addSeries(s3);
    dataset.addSeries(s4);
    return dataset;
}

/**
 * Utility method for creating <code>Date</code> objects.
 * 
 * @param day
 *            the date.
 * @param month
 *            the month.
 * @param year
 *            the year.
 * 
 * @return a date.
 */
private static Date date(Calendar calendar, int daysPlus) {
    final Calendar calendarResult = (Calendar) calendar.clone();
    calendarResult.add(Calendar.DAY_OF_MONTH, daysPlus);
    final Date result = calendarResult.getTime();

    return result;

}

public static void main(String[] paramArrayOfString) {
    Sample localXYTaskDatasetDemo2 = new Sample("Sample");
    localXYTaskDatasetDemo2.pack();
    RefineryUtilities.centerFrameOnScreen(localXYTaskDatasetDemo2);
    localXYTaskDatasetDemo2.setVisible(true);
}

}

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

你打电话给ChartUtilities.applyCurrentTheme覆盖了颜色。

另一件事:当您需要删除标准方法时,应该使用chart.removeLegend()方法。请参阅以下代码以获取解决方案。

private static JFreeChart createChart() {
   CombinedDomainXYPlot localCombinedDomainXYPlot = new CombinedDomainXYPlot(new DateAxis("Time"));

   JFreeChart localJFreeChart = new JFreeChart("Sample", localCombinedDomainXYPlot);
   localCombinedDomainXYPlot.add(createSubplot1(createDataset1()), 1);
   ChartUtilities.applyCurrentTheme(localJFreeChart);
   localJFreeChart.setBackgroundPaint(Color.white);

   final LegendItemCollection legendItemsOld = localCombinedDomainXYPlot.getLegendItems();
   LegendItemSource source = new LegendItemSource() {
      public LegendItemCollection getLegendItems() {
         LegendItemCollection lic = new LegendItemCollection();
         int itemCount = legendItemsOld.getItemCount();
         for (int i = 0; i < itemCount; i++) {
            lic.add(legendItemsOld.get(i));
         }
         return lic;
      }
   };
   localJFreeChart.removeLegend();
   localJFreeChart.addLegend(new LegendTitle(source));
   localJFreeChart.getLegend().setPosition(RectangleEdge.TOP);
   localJFreeChart.getLegend().getItemContainer().getBlocks();

   return localJFreeChart;
}