JFreeChart - 颜色与2传说的问题 [英] JFreeChart - Problem of colors with 2 legends

查看:330
本文介绍了JFreeChart - 颜色与2传说的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to create a customized legend in my chart but something strange happens when I display one or two legends. When I display 2 legends (the old one and the new one), everything is allright, colors are respected in legends and in the graph. But, when I want to display only the new legend, the colors in the legend are respected but the colors in the graph are not respected anymore.

这是一个例子我的问题:
您必须评论和分解一行才能看到问题(见注释)

This is an example on my issue: You have to comment and decomment a line to see the problem (see comments)

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

}

感谢您的帮助。

推荐答案

这是您致电 ChartUtilities.applyCurrentTheme 覆盖了颜色。

It was your call to ChartUtilities.applyCurrentTheme that overwrote the colors.

另一件事:当您需要删除标准版本时,应该使用 chart.removeLegend()方法。

Another thing: You should use the chart.removeLegend() method when you need to remove the standard one. See the following code for the solution.

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

这篇关于JFreeChart - 颜色与2传说的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆