Библиотека JFreeChart

Проект JFreeChart был основан в феврале 2000 года Дэвидом Гилбертом. Сегодня библиотека JFreeChart широко используется в Java приложениях для создания широкого спектра графиков. Используя JFreeChart можно создавать все основные типы 2D и 3D графики : круговые диаграммы, гистограммы, линейные и временные диаграммы. Библиотека позволяет создавать изображения нескольких форматов типа PNG, JPEG, SVG (Scalable Vector Graphics) и т.д.

JFreeChart обеспечена хорошо документированным API, поставляется с открытым исходным кодом и бесплатно. Это позволяет использовать ее в коммерческих целях без каких-либо дополнительных затрат. Документированное описание API можно найти на официальном сайте http://www.jfree.org/jfreechart/api/javadoc.

Дистрибутив JFreeChart

Дистрибутив библиотеки JFreeChart поставляется в виде zip файла и включает maven проект с документацией и демонстрационными примерами. Скачать последнюю версию библиотеки JFreeChart можно с официального сайта http://www.jfree.org/jfreechart/download.html.

Загрузка JFreeChart в maven репозиторий

Артефакт JFreeChart версии 1.0.19 можно найти в репозитории mvnrepository по следующим GAV параметрам :

<!-- https://mvnrepository.com/artifact/org.jfree/jfreechart -->
<dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jfreechart</artifactId>
    <version>1.0.19</version>
</dependency>

Чтобы загрузить библиотеку/артефакт в локальный репозиторий {USER_HOME/}.m2/repository можно использовать плагин dependency с целью (goal) get следующим образом :


mvn dependency:get -Dartifact=org.jfree:jfreechart:1.0.19:jar
 

Примечание : в среде разработки Eclipse библиотеку JFreeChart можно установить как «User Library» и подключать к проектам.

Архитектура библиотеки JFreeChart

На следующем рисунке представлена схема взаимодействия различных классов библиотеки JFreeChart.

ОбъектОписание
FileФайл данных для формирования набора
DataBaseБаза данных для формирования набора
Create DatasetЧтение данных и создание объекта набора данных Dataset
General DatasetНабор данных для создания круговых (pie) диаграмм
Category DatasetЭтот тип набора данных используется для гистограммы, линейный график, и т.д.
Series DatasetОбъект хранения данных серии и для построения линейных диаграмм
Series Collection DatasetРазличные категории наборов данных серии формируют коллекцию серии данных. Этот тип набора данных используется для временных диаграмм
Create ChartМетод создания графического изображения
Frame/ImageПредставление графического изображения либо в Swing панеле JPanel, либо в виде файла изображения.

Подключение библиотеки JFreeChart к приложению

Архитектура прикладного уровня, представленная на следующем рисунке, объясняет, как библиотеку JFreeChart можно подключить к Java приложению.

Программа читает данные на основе которых с использованием JFreeChart API формирует требуемое изображение, которое можно будет либо отобразить в интерфейсе приложения (например Swing приложение), либо сформировать изображение типа JPEG или PNG.

Настройка диаграмм JFreeChart

Структура библиотеки JFreeChart создана таким образом, чтобы можно было статически и динамически настраивать общий вид диаграммы и графическое представление данных. Подробное описание свойств диаграммы JFreeChart представлено здесь. Примеры использования JFreeChart в сервлетах наглядно демонстрируют возможности изменения внешнего вида диаграммы изменением отдельных свойств.

Примеры построения диаграмм JFreeChart

Рассмотрим примеры создания 3-х графических изображений JFreeChart : круговая диаграмма (PieChartDemo.java), гистограмма (BarChartDemo.java) и временная диаграмма (TimeSeriesChartDemo.java). Для этого нам необходимо :

  1. Подготовить наборы данных для построения графиков.
  2. Создать графические объекты типа JFreeChart.
  3. Отобразить графические объекты JFreeChart на экране.

Наборы данных для построения графиков

Основой наборов данных для создания различных графических изображений типа круговых диаграмм и гистограмм является класс AbstractDataset. Данный класс является родителем DefaultPieDataset, используемый для формирования круговых диаграмм, и DefaultCategoryDataset для построения гистограмм. Для построения временной диаграммы используется набор данных TimeSeries и коллекция TimeSeriesCollection, реализующая интерфейс XYDataset.

Набор данных для круговой диаграммы

Метод createDataset формирует набор данных типа PieDataset для создания круговой диаграммы.

/*
 * void setValue(Comparable key, Number value)
 */
private PieDataset createDataset()
{
    DefaultPieDataset dataset = new DefaultPieDataset();
    dataset.setValue("Оплата жилья" , new Double( 7035.8));
    dataset.setValue("Школа, фитнес", new Double( 9200.0));
    dataset.setValue("Развлечение"  , new Double(16450.0));
    dataset.setValue("Дача, стройка", new Double(40000.0));
    return dataset;
}

Метод определения значения setValue получает числовое значение value для ключа key, имеющего тип Comparable.

Набор данных для гистограммы

Метод createDataset формирует набор данных типа CategoryDataset для создания гистограммы.

/*
 * void addValue(double value, Comparable rowKey, Comparable columnKey)
 */
private CategoryDataset createDataset()
{
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    dataset.addValue(52733, "Жена", "Январь");
    dataset.addValue(64535, "Муж" , "Январь");
    dataset.addValue(51345, "Жена", "Февраль");
    dataset.addValue(66896, "Муж" , "Февраль");
    return dataset;
}

Метод addValue получает в качестве параметров вещественное значение value для строки rowKey и колонки columnKey, имеющих тип Comparable.

Набор данных для графика

Метод createDataset формирует набор данных типа XYDataset для создания линейных XY графиков. Сначала создаются два объекта TimeSeries, которые подготавливают наборы данных. После этого воздаются коллекции TimeSeriesCollection, реализующие интерфейсы XYDataset, IntervalXYDataset, XYDomainInfo, XYRangeInfo.

/*
 * void add(RegularTimePeriod period, double value)
 */
private XYDataset createDataset()
{
    TimeSeries s1 = new TimeSeries("График №1");
    s1.add(new Month( 7, 2013), 142.9);
    s1.add(new Month( 8, 2013), 138.7);
    s1.add(new Month( 9, 2013), 137.3);
    s1.add(new Month(10, 2013), 143.9);
    s1.add(new Month(11, 2013), 139.8);
    s1.add(new Month(12, 2013), 137.0);
    s1.add(new Month( 1, 2014), 132.8);
    s1.add(new Month( 2, 2014), 181.8);
    s1.add(new Month( 3, 2014), 167.3);
    s1.add(new Month( 4, 2014), 153.8);
    s1.add(new Month( 5, 2014), 167.6);
    s1.add(new Month( 6, 2014), 158.8);
    s1.add(new Month( 7, 2014), 148.3);
    s1.add(new Month( 8, 2014), 153.9);
    s1.add(new Month( 9, 2014), 142.7);
    s1.add(new Month(10, 2014), 123.2);
    s1.add(new Month(11, 2014), 131.8);
    s1.add(new Month(12, 2014), 139.6);

    TimeSeries s2 = new TimeSeries("График №2");
    s2.add(new Month( 7, 2013), 111.7);
    s2.add(new Month( 8, 2013), 111.0);
    s2.add(new Month( 9, 2013), 109.6);
    s2.add(new Month(10, 2013), 113.2);
    s2.add(new Month(11, 2013), 111.6);
    s2.add(new Month(12, 2013), 108.8);
    s2.add(new Month( 1, 2014), 101.6);
    s2.add(new Month( 2, 2014), 129.6);
    s2.add(new Month( 3, 2014), 123.2);
    s2.add(new Month( 4, 2014), 117.2);
    s2.add(new Month( 5, 2014), 124.1);
    s2.add(new Month( 6, 2014), 122.6);
    s2.add(new Month( 7, 2014), 119.2);
    s2.add(new Month( 8, 2014), 116.5);
    s2.add(new Month( 9, 2014), 112.7);
    s2.add(new Month(10, 2014), 101.5);
    s2.add(new Month(11, 2014), 106.1);
    s2.add(new Month(12, 2014), 110.3);

    TimeSeriesCollection dataset = new TimeSeriesCollection();
    dataset.addSeries(s1);
    dataset.addSeries(s2);

    return dataset;
}

Создание изображений графических объектов JFreeChart

Для построения различных графиков JFreeChart (гистограммы, круговые диаграммы, линейные графики) используется ChartFactory, содержащий большое количество статических перегруженных методов.

Графическое изображение круговой диаграммы

Для создания круговой диаграммы используем метод createPieChart, которому в качестве параметров передаем наименование заголовка, набор данных, флаги создания легенды, всплывающей подсказки и отображения URL. После этого определяем фон графика, выравнивание, цвет и шрифт заголовка и подзаголовка. При настройке plot'a. определяем цвет и наименования секций, шрифт меток секций.

Color[] colors = {new Color(200, 200, 255), new Color(255, 200, 200),
                  new Color(200, 255, 200), new Color(200, 255, 200)};

private JFreeChart createChart(PieDataset dataset)
{
    JFreeChart chart = ChartFactory.createPieChart(
        "Семейные расходы",  // chart title
        dataset,             // data
        false,               // no legend
        true,                // tooltips
        false                // no URL generation
    );

    // Определение фона графического изображения
    chart.setBackgroundPaint(new GradientPaint(new Point(0, 0), 
                                               new Color(20, 20, 20), 
                                               new Point(400, 200),
                                               Color.DARK_GRAY));

    // Определение заголовка
    TextTitle t = chart.getTitle();
    t.setHorizontalAlignment(HorizontalAlignment.LEFT);
    t.setPaint(new Color(240, 240, 240));
    t.setFont(new Font("Arial", Font.BOLD, 26));

    // Определение подзаголовка
    TextTitle source = new TextTitle("Семейные расходы за текущий месяц", 
                                     new Font("Courier New", Font.PLAIN, 12));
    source.setPaint(Color.WHITE);
    source.setPosition(RectangleEdge.BOTTOM);
    source.setHorizontalAlignment(HorizontalAlignment.RIGHT);
    chart.addSubtitle(source);

    PiePlot plot = (PiePlot) chart.getPlot();
    plot.setBackgroundPaint(null);
    plot.setInteriorGap(0.04);
    plot.setOutlineVisible(false);

    RadialGradientPaint rgpBlue  ;
    RadialGradientPaint rgpRed   ;
    RadialGradientPaint rgpGreen ;
    RadialGradientPaint rgpYellow;

    rgpBlue   = createGradientPaint(colors[0], Color.BLUE  );
    rgpRed    = createGradientPaint(colors[1], Color.RED   );
    rgpGreen  = createGradientPaint(colors[2], Color.GREEN );
    rgpYellow = createGradientPaint(colors[3], Color.YELLOW);
	
    // Определение секций круговой диаграммы
    plot.setSectionPaint("Оплата жилья" , rgpBlue  );
    plot.setSectionPaint("Школа, фитнес", rgpRed   );
    plot.setSectionPaint("Развлечения"  , rgpGreen );
    plot.setSectionPaint("Дача, стройка", rgpYellow);
	
    plot.setBaseSectionOutlinePaint(Color.WHITE);
    plot.setSectionOutlinesVisible(true);
    plot.setBaseSectionOutlineStroke(new BasicStroke(2.0f));

    // Настройка меток названий секций
    plot.setLabelFont(new Font("Courier New", Font.BOLD, 20));
    plot.setLabelLinkPaint(Color.WHITE);
    plot.setLabelLinkStroke(new BasicStroke(2.0f));
    plot.setLabelOutlineStroke(null);
    plot.setLabelPaint(Color.WHITE);
    plot.setLabelBackgroundPaint(null);
        
    return chart;
}
private RadialGradientPaint createGradientPaint(Color c1, Color c2)
{
    Point2D center = new Point2D.Float(0, 0);
    float radius = 200;
    float[] dist = {0.0f, 1.0f};
    return new RadialGradientPaint(center, radius, dist,
                                   new Color[] {c1, c2});
}

Подробное описание с примерами настройки интерфейса круговых диаграмм представлено здесь.

Графическое изображение гистограммы

Для создания гистограммы используется метод createBarChart, которому в качестве параметров передаются наименование заголовка, наименование вертикальной оси и набор данных. После этого определяется подзаголовок, фон графика и настраивается plot.

private JFreeChart createChart(CategoryDataset dataset)
{
    JFreeChart chart = ChartFactory.createBarChart(
                      "Семейный доход за текущий год", 
                      null,                   // x-axis label
                      "Доход",                // y-axis label
                      dataset);
    chart.addSubtitle(new TextTitle("В доходе включен только " +
                                    "заработок по основной работе"));
    chart.setBackgroundPaint(Color.white);

    CategoryPlot plot = (CategoryPlot) chart.getPlot();

    NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    BarRenderer renderer = (BarRenderer) plot.getRenderer();
    renderer.setDrawBarOutline(false);
    chart.getLegend().setFrame(BlockBorder.NONE);

    return chart;
}

Описание с примерами настройки интерфейса гистограмм представлено здесь.

Временные диаграммы

Для создания временных диаграмм используется метод createTimeSeriesChart, которому в качестве параметров передаются наименования заголовка, осей абсцисс и ординат, набор данных и флаги представления легенды, отображения всплывающей подсказки, отображения адреса URL. Графики будут отображаться на белом фоне. После этого определяются параметры plot'а типа XYPlot.

Временная шкала (ось абсцисс) будет иметь метки в формате "mm.yyyy". Формат временных меток может быть изменен.


private JFreeChart createChart(XYDataset dataset)
{
    JFreeChart chart = ChartFactory.createTimeSeriesChart(
        "Доходы от рекламы на сайте",  // title
        "",                            // x-axis label
        "Валюта",                      // y-axis label
        dataset,                       // data
        true,                          // create legend
        true,                          // generate tooltips
        false                          // generate URLs
    );

    chart.setBackgroundPaint(Color.white);

    XYPlot plot = (XYPlot) chart.getPlot();
    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);

    XYItemRenderer r = plot.getRenderer();
    if (r instanceof XYLineAndShapeRenderer) {
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
        renderer.setBaseShapesVisible   (true);
        renderer.setBaseShapesFilled    (true);
        renderer.setDrawSeriesLineAsPath(true);
    }

    DateAxis axis = (DateAxis) plot.getDomainAxis();
    axis.setDateFormatOverride(new SimpleDateFormat("MM.YYYY"));

    return chart;
}

Описание с примерами создания и настройки временных диаграмм, а также нанесений аннотаций и маркеров на графики, представлено здесь.

Отображение графических объектов в интерфейсе

Для отображения графических объектов в интерфейсе Swing-приложений создаем объект ChartPanel.

public JPanel createDemoPanel()
{
    JFreeChart chart = createChart(createDataset());
    chart.setPadding(new RectangleInsets(4, 8, 2, 2));
    ChartPanel panel = new ChartPanel(chart);
    panel.setFillZoomRectangle(true);
    panel.setMouseWheelEnabled(true);
    panel.setPreferredSize(new Dimension(600, 300));
    return panel;
}

Графические изображения в интерфейсе

Панель представления графических объектов ChartPanel

ChartPanel наследует (extends) свойства Swing GUI класса JPanel и предназначена для отображения графических объектов JFreeChart. Класс содержит несколько конструкторов, которые в качестве основного параметра получают объект JFreeChart.

public ChartPanel(JFreeChart chart);
public ChartPanel(JFreeChart chart, boolean useBuffer);
public ChartPanel(JFreeChart chart, boolean properties,
                                    boolean save,
                                    boolean print,
                                    boolean zoom,
                                    boolean tooltips);
public ChartPanel(JFreeChart chart, int width, int height,
                                    int minimumDrawWidth,
                                    int minimumDrawHeight,
                                    int maximumDrawWidth,
                                    int maximumDrawHeight,
                                    boolean useBuffer,
                                    boolean properties, boolean save, 
                                    boolean print, boolean zoom,
                                    boolean tooltips);
public ChartPanel(JFreeChart chart, int width, int height,
                                    int minimumDrawWidth,
                                    int minimumDrawHeight,
                                    int maximumDrawWidth,
                                    int maximumDrawHeight,
                                    boolean useBuffer,
                                    boolean properties, boolean copy,
                                    boolean save, boolean print, 
                                    boolean zoom, boolean tooltips)

Создаваемое графическое изображение отображается на панели и автоматически перерисовывается при получении соответствующих уведомлений.

Значения по умолчанию

DEFAULT_BUFFER_USED = trueиспользование буфера для увеличения производительности
DEFAULT_WIDTH = 680 размер панели по горизонтали
DEFAULT_HEIGHT = 420 размер панели по вертикали
DEFAULT_MINIMUM_DRAW_WIDTH = 300минимальное значение по горизонтали, ниже которого качество масштабирование графика падает;
DEFAULT_MINIMUM_DRAW_HEIGHT = 200минимальное значение по вертикали, ниже которого качество масштабирование графика падает;
DEFAULT_MAXIMUM_DRAW_WIDTH = 1024максимальное значение по горизонтали, выше которого качество масштабирование графика падает;
DEFAULT_MAXIMUM_DRAW_HEIGHT = 768максимальное значение по вертикали, выше которого качество масштабирование графика падает;

Методы ChartFactory для создания графических объектов JFreeChart

Для создания круговых диаграмм ChartFactory содержит следующие перегруженные методы :

public static JFreeChart createPieChart(String title, 
                                        PieDataset dataset);
public static JFreeChart createPieChart(String title, 
                                        PieDataset dataset,
                                        boolean legend,
                                        boolean tooltips,
                                        boolean urls);
public static JFreeChart createPieChart(String title, 
                                        PieDataset dataset,
                                        PieDataset previousDataset,
                                        int percentDiffForMaxScale,
                                        boolean greenForIncrease,
                                        boolean legend,
                                        boolean tooltips,
                                        Locale locale,
                                        boolean subTitle,
                                        boolean showDifference);
public static JFreeChart createPieChart(String title,
                                        PieDataset dataset,
                                        PieDataset previousDataset,
                                        int percentDiffForMaxScale,
                                        boolean greenForIncrease,
                                        boolean legend,
                                        boolean tooltips, 
                                        boolean urls,
                                        boolean subTitle,
                                        boolean showDifference);

Для создания гистограмм ChartFactory включает следующие методы :

public static JFreeChart createBarChart(String title,
                                        String categoryAxisLabel,
                                        String valueAxisLabel,
                                        CategoryDataset dataset);
public static JFreeChart createBarChart(String title,
                                        String categoryAxisLabel,
                                        String valueAxisLabel,
                                        CategoryDataset dataset,
                                        PlotOrientation orientation,
                                        boolean legend,
                                        boolean tooltips,
                                        boolean urls);

ChartFactory содержит два перегруженных метода создания линейых временных графиков :

public static JFreeChart createTimeSeriesChart(String title,
                                               String timeAxisLabel,
                                               String valueAxisLabel,
                                               XYDataset dataset);
public static JFreeChart createTimeSeriesChart(String title,
                                               String timeAxisLabel,
                                               String valueAxisLabel, 
                                               XYDataset dataset,
                                               boolean legend,
                                               boolean tooltips,
                                               boolean urls);

В качестве параметров эти методы получают заголовок, наименования временной горизонтальной оси timeAxisLabel и оси значений valueAxisLabel, набор данных типа XYDataset. Второму методу дополнительно необходимо передать флаги отображения легенды, всплывающей подсказки значений на графике и отображения строки URL.

С примерами построения линейных диаграмм можно познакомиться здесь.

Скачать примеры

Исходные коды рассмотренных примеров создания различных графических изображений в виде maven-проекта можно скачать здесь (23.8 Кб).

  Рейтинг@Mail.ru