Board index JavaServer Faces General JFreeChart

JFreeChart

Components, Ajax Framework, Utilities and More.

Post 03 Nov 2009, 18:30

Posts: 8
Hey guys,

I'd like to use PrimeFaces with JFreeChart. I found an example which seems good : http://cagataycivici.wordpress.com/?s=StreamedImage

Problem is that this example uses class named StreamedImage (org.primefaces.ui.io.StreamedImage), which is not contained in the prime faces jar file (though it's mentioned in the documentation).
I've tried to use StreamedConted class instead, but it doesn't seem to work. Can there be a problem because I use PrimeFaces in combination with Spring WebFlow ?

Thanks to everyone.

P.

Post 03 Nov 2009, 18:42

Posts: 15042
Location: Cybertron

Hi, the correct name of the class is;

org.primefaces.ui.model.io.StreamedImage for now, this week ui part will be removed due to reorganization in PrimeFaces. But if you have 0.9.3, that should work.
PrimeFaces Lead

Post 04 Nov 2009, 11:33

Posts: 8
Hi,

thank you very much for such a quick response. However, the org.primefaces.ui.model.io.StreamedImage class doesn't exist either in the JAR file (primefaces-ui-0.9.3.jar). There is only org.primefaces.ui.model.io.StreamedContent. Is that what you meant ?
If I use the StreamedContent class, I don't get any exception, but the chart is simply not displayed on the page. I'm afraid it has something to do with the fact that I'm using Spring Web Flow and that I'm storing the created chart in the request scope.

Thanks again.

Post 04 Nov 2009, 11:37

Posts: 15042
Location: Cybertron

Did I say StreamedImage? Oh yes typo, it should be StreamedContent. If you post your code, we'll try to help. I also play with spring webflow nowadays myself, due to the spring centric approach(no actual faces servlet mapping), incompatibilites might occur.
PrimeFaces Lead

Post 04 Nov 2009, 12:50

Posts: 8
First of all, your response time is extraordinary. :-) I've never seen anyhting like this... At the Spring forums I usually have to wait for days to receive an answer... bravo... :-)

So, my code is following :

Creation of the Chart in Java :

      public StreamedContent createExperimentalChart() throws IOException {
     
        StreamedContent sc = null;
       
       CategoryDataset dataset = createDataset();
        JFreeChart chart = createChart(dataset);       
       
        File chartFile = new File("c:\\My\\CSC\\JAVA\\SpringSource\\ws\\lenin\\dynamichart");
        ChartUtilities.saveChartAsPNG(chartFile, chart, 375, 300);
        sc = new DefaultStreamedContent(new FileInputStream(chartFile), "image/png");
       
        return sc;
    }
    
   
   /**
     * Creates a sample dataset.
     *
     * @return A sample dataset.
     */
    private CategoryDataset createDataset() {
        final double[][] data = new double[][] {
            {3.0, 4.0, 3.0, 5.0},
            {5.0, 7.0, 6.0, 8.0},
            {5.0, 7.0, 3.0, 8.0},
            {1.0, 2.0, 3.0, 4.0},
            {2.0, 3.0, 2.0, 3.0}
        };
       final CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
            "Region ",
            "Sales/Q",
            data
        );
        return dataset;
    }   
   
   /**
     * Creates a sample chart with the given dataset.
     *
     * @param dataset  the dataset.
     *
     * @return A sample chart.
     */
    private JFreeChart createChart(final CategoryDataset dataset) {
        final JFreeChart chart = ChartFactory.createMultiplePieChart(
            "Multiple Pie Chart",  // chart title
            dataset,               // dataset
            TableOrder.BY_ROW,
            true,                  // include legend
            true,
            true
        );
        final MultiplePiePlot plot = (MultiplePiePlot) chart.getPlot();
        final JFreeChart subchart = plot.getPieChart();
        final PiePlot p = (PiePlot) subchart.getPlot();
        p.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}"));
        p.setLabelFont(new Font("SansSerif", Font.PLAIN, 8));
        p.setInteriorGap(0.30);
       
        return chart;
    }
     



Spring Web Flow definition file:

 
  <view-state id="ratingCompetencyReportDetailView" view="ReportDetail.xhtml">       
       <on-entry>
       <evaluate expression="chartImages.createExperimentalChart()" result="requestScope.chartData"></evaluate>
   </on-entry>
      ...      
  </view-state>
 




XHTML Page:

   <p:graphicImage value="#{chartData}" />
   



I really appreciate your help.

Post 04 Nov 2009, 14:04

Posts: 15042
Location: Cybertron

First of all, your response time is extraordinary.


Don't get used to it so much, it depends on how much free time and volume of questions we get. ;)

Can you put your chartData to session of flowscope to see it makes a difference.
PrimeFaces Lead

Post 04 Nov 2009, 17:06

Posts: 8
Unfortunaltely it didn't make any difference. I even tried to store the data in a session scoped spring bean and access it through getter method. The data is there - i put a logging statement into the getter, but it's not displayed on the page. I'm starting to believe it's because of the Spring Webflow.
Can it be that the resource servlet is not applied correctly ?

I have this configuration in my web.xml :

<servlet>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>org.primefaces.ui.resource.ResourceServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Resource Servlet</servlet-name>
  <url-pattern>/primefaces_resources/*</url-pattern>
</servlet-mapping>


But when the HTML page is generated, the chart image looks like this :

<!--Start: org.primefaces.ui["j_id36"]--><img id="j_id36" src="/dwa/web/main?execution=e1s4&amp;amp;primefacesDynamicImage=chartImages.sc">


Shouldn't the 'primefaces_resources' string be included in the image url ?

I have the <p:resources /> tag in my template's head. I'm using trinidad library, so it looks something like this :

<tr:document styleClass="tundra spring">

  <trh:head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <title>#{resourceBundle['application.title']}
     #{resourceBundle['application.version']}</title>

     <sf:includeStyles />
     <sf:resourceGroup>
     <sf:resource path="/css-framework/css/tools.css" />
     <sf:resource path="/css-framework/css/typo.css" />
     <sf:resource path="/css-framework/css/forms.css" />
     <sf:resource path="/css-framework/css/layout.css" />
     </sf:resourceGroup>
     <sf:resource path="/styles/styles.css" />

     <p:resources />

     <f:loadBundle basename="jsf-messages" var="msg" />
  </trh:head>

Post 04 Nov 2009, 18:16

Posts: 15042
Location: Cybertron

No, you don't need to use primefaces_resources anywhere, it is for internal use only.

The url generated is: primefacesDynamicImage=chartImages.sc

Which means a valueexpression like #{chartImages.sc} will be evaluated and needs to return a streamed image. Do you know what #{chartImage.sc} can refer to in your app?
PrimeFaces Lead

Post 04 Nov 2009, 20:22

Posts: 8
#{chartImage.sc} refers to the StreamedContent variable containig data of the chart. chartImage is session scoped bean and has getter method getSc() returning the created chart. There is no problem. I verified that when the JSF page is rendered, this getter is invoked and returns created StreamedContet object.

I think that the problem is in the resource servlet, which is not being applied.

<servlet>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>org.primefaces.ui.resource.ResourceServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Resource Servlet</servlet-name>
  <url-pattern>/primefaces_resources/*</url-pattern>
</servlet-mapping>[


In order for the Resource Servlet to be apllied, particular request has to match "/primefaces_resources/*" url pattern, right ? - as defined in web.xml.
Therefore i expected that the generated html element <img would contain this string in its src attribute. I don't mean the <p:graphicImage in XHTML page, but the <img HTML element generated from it when the page is rendered.

So that it would look somehow like this :

<img id="j_id36" src="/dwa/primefaces_resources/?primefacesDynamicImage=chartImages.sc">


instead of what i get :

<img id="j_id36" src="/dwa/web/main?execution=e1s4&amp;amp;primefacesDynamicImage=chartImages.sc">

Which is no different from typical SWF application request - therefore it's not handled by Primefaces Resource Servlet, but Spring WebFlow Dispatcher Servlet.
This request is then dispatched to the Spring WebFlow controller and handled as if it was normal weblflow request, not request for an image.
No wonder then that the image is not found and returned to the page. Am i wrong ?

I don't know whether i expressed myself clearly. But my question is simple. When rendering the page and makind request for the image representing the chart, how does the application decide from this url ("/dwa/web/main?execution=e1s4&amp;amp;primefacesDynamicImage=chartImages.sc"), that this request should be handled by Primefaces Resource Servlet and not Spring's Dispatcher Servlet ? The only way how it could go to the Resource Servlet (under current configuration) is if it folloved the "/primefaces_resources/*" pattern.

Thank you in advance for any comments.

Post 04 Nov 2009, 22:45

Posts: 15042
Location: Cybertron

primefaces_resources request is only for loading js and css bundled with primefaces jar, it has nothing to do with charts. The url is calculated with ViewHandler getActionURL api which is the current page you're accessing so the url of chart request should be similar to your actual page request containing the chart.

Can you see with firebug what the chart img src request returns meaning;

<img id="j_id36" src="/dwa/web/main?execution=e1s4&amp;amp;primefacesDynamicImage=chartImages.sc">
PrimeFaces Lead

Next

Return to General