JFreeChart in portlet
Asked Answered
E

2

0

I want to change the color of my Chart(Pie) (background Color dataset colors and so on ..) via a button or menu selection klick from an portlet (Vaadin / Liferay portal) . i kinda have no clue how to do that Here is my Servlet :

import org.jfree.data.jdbc.JDBCPieDataset;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.sql.DriverManager;
import java.sql.Connection;

public class PieChart extends HttpServlet {


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

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Connection connection = null;
    try {
      Class.forName("org.postgresql.Driver").newInstance();
      try {
            connection = DriverManager.getConnection(
                    "jdbc:postgresql://localhost:5432/db", "user",
                    "password");
      } catch (SQLException e) {
        e.printStackTrace();
      }
    } 
    catch (InstantiationException e) {
      e.printStackTrace();
    } 
    catch (IllegalAccessException e) {
      e.printStackTrace();
    } 
    catch (ClassNotFoundException e) {
      e.printStackTrace();
    }

    JDBCPieDataset dataset = new JDBCPieDataset(connection);
    try {
      dataset.executeQuery("Select * From my_table");
      JFreeChart chart = ChartFactory.createPieChart("Pie Chart", dataset, true, false, false);
      if (chart != null) {
        response.setContentType("image/png");
        OutputStream out = response.
        getOutputStream();
        ChartUtilities.writeChartAsPNG(out, chart, 450, 400);
      }
    } 
    catch (SQLException e) {
      e.printStackTrace();
    }
    try {
      if(connection != null){connection.close();} 
    }
    catch (SQLException e) {e.printStackTrace();}
}

what i want to do is , to send the Selected Color to the Servlet so the Color changes when i klick on a menu selection ( already have the menu ).

Any guide or similar would be great.


now lets say i want to change the background color of the chart. i would use chart.setBackgroundPaint(Color.blue); in the servlet to change the color manualy . but i want to do it from the portlet this is what i have tryed to do:

PieChart pie;

in the init method i configure the menu and try to send the color on click

final MenuBar.MenuItem config = menubar.addItem("Config", null);

 newItem.addItem("PieChart", new Command(){
       public void menuSelected(MenuItem selectedItem) {
           pie.chart.setBackgroundPaint(Color.blue);
       }
 });

i use the same to change the background color of a subwindow from another class it works fine but does not seem to work within a servlet .

Economize answered 6/9, 2011 at 13:25 Comment(1)
Btw: you should have a look at the concept of connection pooling (javax.sql.DataSource)...Jolenejolenta
P
2

You need to understand that the portlet's action phase (which gets fired when the menu is clicked) and the servlet request are entirely separate requests.

I don't know the intricacies of Vaadin, but I'm assuming it's a server-side component model like JSF. So in your menuSelected method you need to change the colour of your chart (which I see you do via an amendment to your question). This is correct, but how is pie and its data shared with the servlet? It is the servlet that will be using the colour, so you need to pass it somehow. This can be via one of several methods, of which a couple are listed here:

  • shared session state
  • url parameter

Ordinarily, shared session state is a bad idea because it tightly couples components together. And URL parameters can be a bad option if the parameters contain sensitive data. But for your example URL parameters are perfectly fine.

So going by the information you wrote in the comment, you use a Label component to render the <img> tag. You say something like:

new Label("img link",Label.CONTEXT_XHTML));

So this can now add URL parameters to the servlet, like:

new Label("<img src='/path/to/servlet?background=blue'>",Label.CONTEXT_XHTML));

So this URL parameter will be visible to the servlet, which can read it from the request parameters (as in the example below) and set the colour on the chart.

Aside from the requirement of getting input from the user, I would rearrange your code a bit. Mostly to move the JDBC driver initialisation to the servlet's init() method, and to ensure the connection is closed in a finally block. @home also makes a valid comment that ideally you would be using a connection pool to grab the connection.

I've added some comments to show how you would grab a request parameter and use it with your chart. (EDIT - and added some rudimentary logic for setting the colour).

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

    public void init() throws ServletException {
        super.init();
        try {
            Class.forName("org.postgresql.Driver").newInstance();
        } catch (InstantiationException e) {
            throw new ServletException(e);
        } catch (IllegalAccessException e) {
            throw new ServletException(e);
        } catch (ClassNotFoundException e) {
            throw new ServletException(e);
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String background = request.getParameter("background");
        // do some checks on colour here
        // such as null check and checking it is a valid colour value for your
        // chart

        Connection connection = null;
        try {
            connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/db", "user", "password");
            JDBCPieDataset dataset = new JDBCPieDataset(connection);
            dataset.executeQuery("Select * From my_table");
            JFreeChart chart = ChartFactory.createPieChart("Pie Chart", dataset, true, false, false);

            if ("blue".equals(background)) {
                chart.setBackgroundPaint(Color.blue)
            }

            // why the null test? can chart ever be (sensibly) null?
            if (chart != null) {
                response.setContentType("image/png");
                OutputStream out = response.getOutputStream();
                ChartUtilities.writeChartAsPNG(out, chart, 450, 400);
            }
        } catch (SQLException e) {
            log("Exception retrieving chart data", e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    log("Could not close Connection", e);
                }
            }
        }
    }
}
Pepe answered 6/9, 2011 at 17:25 Comment(3)
To display the image in my portlet i use indeed the img tag : (vaadin) Window window = new Window(new Label("img link",Label.CONTEXT_XHTML)); works fine for me (for now).Economize
perfect , just what i needed I owe you one :)Economize
Great! Thanks for your comment and if you require anything else then let me know.Pepe
K
2

The class org.jfree.chart.StandardChartTheme is the "default implementation of the ChartTheme interface." The source is a good way to see all the possibilities.

Killing answered 6/9, 2011 at 16:55 Comment(0)
P
2

You need to understand that the portlet's action phase (which gets fired when the menu is clicked) and the servlet request are entirely separate requests.

I don't know the intricacies of Vaadin, but I'm assuming it's a server-side component model like JSF. So in your menuSelected method you need to change the colour of your chart (which I see you do via an amendment to your question). This is correct, but how is pie and its data shared with the servlet? It is the servlet that will be using the colour, so you need to pass it somehow. This can be via one of several methods, of which a couple are listed here:

  • shared session state
  • url parameter

Ordinarily, shared session state is a bad idea because it tightly couples components together. And URL parameters can be a bad option if the parameters contain sensitive data. But for your example URL parameters are perfectly fine.

So going by the information you wrote in the comment, you use a Label component to render the <img> tag. You say something like:

new Label("img link",Label.CONTEXT_XHTML));

So this can now add URL parameters to the servlet, like:

new Label("<img src='/path/to/servlet?background=blue'>",Label.CONTEXT_XHTML));

So this URL parameter will be visible to the servlet, which can read it from the request parameters (as in the example below) and set the colour on the chart.

Aside from the requirement of getting input from the user, I would rearrange your code a bit. Mostly to move the JDBC driver initialisation to the servlet's init() method, and to ensure the connection is closed in a finally block. @home also makes a valid comment that ideally you would be using a connection pool to grab the connection.

I've added some comments to show how you would grab a request parameter and use it with your chart. (EDIT - and added some rudimentary logic for setting the colour).

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

    public void init() throws ServletException {
        super.init();
        try {
            Class.forName("org.postgresql.Driver").newInstance();
        } catch (InstantiationException e) {
            throw new ServletException(e);
        } catch (IllegalAccessException e) {
            throw new ServletException(e);
        } catch (ClassNotFoundException e) {
            throw new ServletException(e);
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String background = request.getParameter("background");
        // do some checks on colour here
        // such as null check and checking it is a valid colour value for your
        // chart

        Connection connection = null;
        try {
            connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/db", "user", "password");
            JDBCPieDataset dataset = new JDBCPieDataset(connection);
            dataset.executeQuery("Select * From my_table");
            JFreeChart chart = ChartFactory.createPieChart("Pie Chart", dataset, true, false, false);

            if ("blue".equals(background)) {
                chart.setBackgroundPaint(Color.blue)
            }

            // why the null test? can chart ever be (sensibly) null?
            if (chart != null) {
                response.setContentType("image/png");
                OutputStream out = response.getOutputStream();
                ChartUtilities.writeChartAsPNG(out, chart, 450, 400);
            }
        } catch (SQLException e) {
            log("Exception retrieving chart data", e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    log("Could not close Connection", e);
                }
            }
        }
    }
}
Pepe answered 6/9, 2011 at 17:25 Comment(3)
To display the image in my portlet i use indeed the img tag : (vaadin) Window window = new Window(new Label("img link",Label.CONTEXT_XHTML)); works fine for me (for now).Economize
perfect , just what i needed I owe you one :)Economize
Great! Thanks for your comment and if you require anything else then let me know.Pepe

© 2022 - 2024 — McMap. All rights reserved.