Диаграммы JFreeChart в сервлетах

Java Servlet относится к популярным WEB-технологиям представления информации. Возможность использования библиотеки JFreeChart в сервлетах позволяет сделать информацию на сайте более привлекательной. На этой странице на примерах покажем возможность представления сервлетами графических изображений, создаваемых библиотекой JFreeChart. Дополнительно продемонстрируем возможности управления некоторыми свойствами настройки диаграмм JFreeChart.

Структура приложения

На следующем скриншоте представлена структура проекта приложения, включающего :

• 1-й пример- сервлет ServletChart1.java и страница chart1.html;
• 2-й пример- сервлеты ServletChart2.java, ServletChart2Generator.java и страница chart2.html;
• Dataset.java- набор данных для создания диаграмм;
• web.xml- дескриптор приложения;
• index.html- общая страница, открываемая по умолчанию.

1-ый пример диаграммы с выделением значений

На скриншоте представлен интерфейс созданной 1-м сервлетом страницы с диаграммой BarChart. Из диаграммы удалена ось абсцисс и определенные значения набора данных на графике выделены.

Набор данных

Допустим, что имеются данные некоторых исследований, полученные при разных условиях. Всего было проведено 4 исследования ("Object"), определяющие количество объектов. При каждом исследовании изменялись значения одних параметров и фиксировались значения других зависимых параметров. Общее количество параметров одного исследования составляет 9 ("Param").

Метод getCategoryDataset() класса Dataset.java формирует набор данных типа DefaultCategoryDataset.

public DefaultCategoryDataset getCategoryDataset()
{
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    dataset.addValue( 23.0, "Param1", "Object1");
    dataset.addValue( 14.0, "Param1", "Object2");
    dataset.addValue( 18.0, "Param1", "Object3");
    dataset.addValue( 19.0, "Param1", "Object4");
    . . .
    dataset.addValue(-12.0, "Param9", "Object1");
    dataset.addValue( 19.0, "Param9", "Object2");
    dataset.addValue( 21.0, "Param9", "Object3");
    dataset.addValue( -2.0, "Param9", "Object4");
    return dataset;
}

Сервлет ServletChart1

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

Класс CategoryMarker (Comparable) позволяет выделить значения объектов "Object2" и "Object4" на диаграмме. Сначала объекты выделяемых значений настраиваются. Для этого конструктору передается наименование объекта. После этого устанавливается уровень прозрачности методом setAlpha(float). Чтобы объект был выделен используется метод addDomainMarker (CategoryMarker, Layer) класса CategoryPlot.

В заключение методом writeChartAsPNG (OutputStream, JFreeChart, width, height) библиотечной утилиты ChartUtilities диаграмма экспортируется в изображение формата PNG заданного размера, которое записывается в выходной поток сервлета.

public class ServletChart1 extends HttpServlet
{
    private static final long serialVersionUID = 1L;

    public ServletChart1() {}

    public void doGet(HttpServletRequest request, 
                      HttpServletResponse response)
                            throws ServletException, IOException
    {
        OutputStream           out     = null;
        Dataset                dao     = null;
        DefaultCategoryDataset dataset = null;
        JFreeChart             chart   = null;
        response.setContentType("image/png");
        try {
            dao     = new Dataset();
            dataset = dao.getCategoryDataset();
            chart = ChartFactory.createBarChart("Диаграмма значений", 
                                                null, "Уровень",
                                                dataset,
                                                PlotOrientation.VERTICAL,
                                                true, true, false);
            // Удаление оси абсцисс
            CategoryPlot plot = chart.getCategoryPlot();
            Axis         axis = plot.getDomainAxis();
            axis.setTickLabelsVisible(false);  // метки значений оси
            axis.setAxisLineVisible(false);    // осевая линия
            axis.setTickMarksVisible(false);   // метки деления оси 
            
            CategoryMarker cm2 = new CategoryMarker("Object2");
            cm2.setAlpha(0.5f);
            CategoryMarker cm4 = new CategoryMarker("Object4");
            cm2.setAlpha(0.5f);
            chart.getCategoryPlot().addDomainMarker(cm2, Layer.BACKGROUND);
            chart.getCategoryPlot().addDomainMarker(cm4, Layer.BACKGROUND);

            response.setContentType("image/png");
            // Экспорт диаграммы в PNG
            out = response.getOutputStream();
            ChartUtilities.writeChartAsPNG(out, chart, 600, 400);
        } catch (Exception e) {
            System.err.println(e.toString());
        } finally {
            out.close();
        }
    }
}

2-ой пример сервлета с представлением двух диаграмм JFreeChart

Сервлет ServletChart2.java формирует общий интерфейс страницы, в которой вызывается сервлет ServletChart2Generator. В зависимости от выбранного на странице chart2.html параметра "chart" ServletChart2Generator создает соответствующую диаграмму, экспортирует ее в изображение PNG и записывает в выходной поток сервлета.

Листинг метода doPost сервлета ServletChart2

Сервлет ServletChart2.java в методе doPost формирует и записывает в выходной поток страницу, повторяющую текст страницы chart2.html. При нажатии на кнопку "Generate chart" вызывается сервлет ServletChart2Generator.java с параметром "type".

public void doPost(HttpServletRequest request, 
                   HttpServletResponse response)
                             throws ServletException, IOException
{
    PrintWriter out = new PrintWriter(response.getWriter());
    try {
        String param = request.getParameter("chart");
        response.setContentType("text/html");

        out.println("<!DOCTYPE html PUBLIC " +
                    "\"-//W3C//DTD HTML 4.01 Transitional//EN\" " +
                    "\"http://www.w3.org/TR/html4/loose.dtd\"> ");
        out.println("<html>");
        out.println("<head>");
        out.println("<meta charset=\"UTF-8\">");
        out.println("<title>JFreeChart : servlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<H2>JFreeChart Servlet</H2>");
        out.println("<P>");
        out.println("Please choose a chart type :");
        out.println("<FORM ACTION=\"ServletChart2\" METHOD=POST>");
        String barChecked  = (param.equals( "bar") ? " CHECKED" : "");
        String lineChecked = (param.equals("line") ? " CHECKED" : "");
        out.println("<INPUT TYPE=\"radio\" NAME=\"chart\"
                      VALUE=\"bar\"" + barChecked + "> Bar Chart");
        out.println("<INPUT TYPE=\"radio\" NAME=\"chart\" 
                      VALUE=\"line\"" + lineChecked + "> Line Chart");
        out.println("<P>");
        out.println("<INPUT TYPE=\"submit\" VALUE=\"Generate chart\">");
        out.println("</FORM>");
        out.println("<P>");
        out.println("<IMG SRC=\"ServletChart2Generator?type=" + param
                             + "\" BORDER=1 WIDTH=600 HEIGHT=400/>");
        out.println("</body>");
        out.println("</html>");

        out.flush();
    } catch (Exception e) {
        System.err.println(e.toString());
    } finally {
        out.close();
    }
}

Интерфейс страницы chart2.html, а также страницы, создаваемой сервлетом ServletChart2.java (без диаграммы) представлен на следующем скриншоте.

Листинг метода doGet сервлета ServletChart2Generator

Сервлет ServletChart2Generator.java вызывается с параметром "type". В зависимости от его значения создается диаграмма одним из методом createBarChart() или createLineChart(). После этого диаграмма экспортируется в изображение PNG и записывается в выходной поток серлета OutputStream.

public void doGet(HttpServletRequest request, 
                  HttpServletResponse response)
                             throws ServletException, IOException {
    OutputStream out = response.getOutputStream();
    try {
        String type = request.getParameter("type");
        JFreeChart chart = null;
        if (type.equals("bar"))
            chart = createBarChart();
        else if (type.equals("line"))
            chart = createLineChart();

        if (chart != null) {
            response.setContentType("image/png");
            ChartUtilities.writeChartAsPNG(out, chart, 600, 400);
        }
    } catch (Exception e) {
        System.err.println(e.toString());
    } finally {
        out.close();
    }
}

Диаграмма Bar Chart

Для создания диаграммы Bar Chart используются данные 1-го примера, т.е. по сути будет создана диаграмма 1-примера. Внесем небольшие изменения во внешний вид диаграммы и повернем её на 90°. Для этого в методе создания диаграммы createBarChart определим значение ориентации PlotOrientation.HORIZONTAL. Дополнительно :

  • изменим фон графика, используя метод setBackgroundPaint(Color), определяющий цвет, и метод setBackgroundAlpha (float), определяющий прозрачность;
  • определим цвет сетки графика методами setDomainGridlinePaint (Color) и setRangeGridlinePaint (Color);
  • перенесем ось абсцисс вниз методом setRangeAxisLocation (AxisLocation), т.к. после поворота графика на 90° ось RangeAxis переместилась вверх по часовой стрелке.
private JFreeChart createBarChart()
{
    JFreeChart             chart   = null;
    Dataset                dao     = new Dataset();
    DefaultCategoryDataset dataset = dao.getCategoryDataset();
    chart = ChartFactory.createBarChart("Диаграмма значений", 
                                        null, "Уровень",
                                        dataset,
                                        PlotOrientation.HORIZONTAL,
                                        true, true, false);
    CategoryPlot plot = chart.getCategoryPlot();
    // Определение фона 
    plot.setBackgroundPaint(Color.lightGray);
    plot.setBackgroundAlpha(0.2f);
    // Цвет сетки на графике
    plot.setDomainGridlinePaint(Color.gray);
    plot.setRangeGridlinePaint (Color.gray);
    // Размещение цифровой оси в нижней части диаграммы  
    plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
    // Выделение объектов
    CategoryMarker cm2 = new CategoryMarker("Object2");
    cm2.setAlpha(0.5f);
    CategoryMarker cm4 = new CategoryMarker("Object4");
    cm4.setAlpha(0.5f);
    chart.getCategoryPlot().addDomainMarker(cm2, Layer.BACKGROUND);
    chart.getCategoryPlot().addDomainMarker(cm4, Layer.BACKGROUND);

    return chart;
}

Интерфейс созданной сервлетом страницы с диаграммой JFreeChart представлен на следующем скриншоте. Сравните со скриншотом 1-го примера.

Диаграмма Line Chart

На второй диаграмме сервлета Line Chart будут представлены 3 графика. У первого графика отобразим спецзнаками только значения, связующие линии исключим. Каждый график имеет собственные спецзнаки, размещаемые в соответствующих позциях plot'a. Дополнительно изменим цвет фона на бледно-серый, удалим осевые линии и определим серый цвет сетки графика.

Интерфейс созданной сервлетом страницы с диаграммой представлен на следующем скриншоте.

Наборы данных диаграммы Line Chart

Метод getXYDataset() класса Dataset.java формирует коллекцию типа XYSeriesCollection, включающую данные типа XYSeries для построения трёх графиков.

public XYDataset getXYDataset()
{
    final XYSeries series1 = new XYSeries("First");
    series1.add ( 2.2, 1.3);
    series1.add ( 4.4, 4.2);
    series1.add ( 6.6, 5.5);
    series1.add ( 8.7, 5.8);
    series1.add (11.9, 5.6);
    series1.add ( 7.7, 7.9);
    series1.add ( 5.6, 7.1);
    series1.add ( 3.5, 8.2);

    final XYSeries series2 = new XYSeries("Second");
    series2.add (2.4, 5.5);
    series2.add (4.7, 7.7);
    series2.add (6.6, 6.9);
    series2.add (8.5, 8.8);
    series2.add (9.8, 4.6);
    series2.add (2.3, 4.4);
    series2.add (1.0, 2.2);
    series2.add (3.1, 1.0);

    final XYSeries series3 = new XYSeries("Third");
    series3.add (11.1, 4.4);
    series3.add ( 9.3, 3.6);
    series3.add ( 7.5, 2.8);
    series3.add ( 5.7, 3.9);
    series3.add ( 8.9, 6.6);
    series3.add ( 6.8, 3.4);
    series3.add (12.2, 4.3);
    series3.add (10.4, 3.2);

    final XYSeriesCollection dataset = new XYSeriesCollection();
    dataset.addSeries(series1);
    dataset.addSeries(series2);
    dataset.addSeries(series3);

    return dataset;        
}

Листинг метода createLineChart

Сервлет создает диаграмму методом createXYLineChart() класса ChartFactory. Настройка цвета фона графика XYPlot выполняется точно также, как и в предыдущем примере. После удаления осевых линий настраиваем отступ осевых меток делений методом setAxisOffset(RectangleInsets).

private JFreeChart createLineChart()
{
    Dataset    dao     = new Dataset();
    XYDataset  dataset = dao.getXYDataset();

    final JFreeChart chart = ChartFactory.createXYLineChart(
                    "Line Chart",             // chart title
                    "X",                      // x axis label
                    "Y",                      // y axis label
                    dataset,                  // data
                    PlotOrientation.VERTICAL,
                    true, true, false);
    XYPlot plot = chart.getXYPlot();
    // Цвет фона графика
    plot.setBackgroundPaint(Color.lightGray);
    plot.setBackgroundAlpha(0.2f);

    // Цвет осей на диаграмме
    plot.setDomainGridlinePaint(Color.gray);
    plot.setRangeGridlinePaint (Color.gray);
        
    // Удаляем из диаграммы осевые линии
    ValueAxis axis = plot.getRangeAxis();  // RangeAxis
    axis.setAxisLineVisible(false);
    axis = plot.getDomainAxis();           // DomainAxis
    axis.setAxisLineVisible(false);

    // Определение отступа меток делений  
    plot.setAxisOffset(new RectangleInsets (1.0, 1.0, 1.0, 1.0));
	
    // Исключаем представление линий 1-го графика
    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
    renderer.setSeriesLinesVisible (0, false);
    plot.setRenderer(renderer);

    return chart; 
}

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

Исходный код приложения использования JFreeChart в сервлетах в виде проекта Eclipse можно скачать здесь (1.72 Мб). Приложение включает библиотечный файл jfreechart-1.0.19.jar.

  Рейтинг@Mail.ru