JFreeChart - проблема цветов с 2 легендами - PullRequest
3 голосов
/ 27 апреля 2011

Я пытаюсь создать настраиваемую легенду на моем графике, но происходит нечто странное, когда я отображаю одну или две легенды.Когда я отображаю 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 Ответ

3 голосов
/ 22 июня 2011

Это был ваш звонок 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;
}
...