When you use jFreeChart, it outputs an image file, with a name and location which you specify.
Get the image output to a folder under your web application.
In your jsp, first call jFreeChart so that it updates the chart, then call the image into the html as you would for a normal image, using the name you specified in jFreeChart.
Hello,
okay thank you I already used this way, I thought it does exist an easier solution than saving the chart every time to a file and extract it again.
But there occur two problems:
1) How can I specify a foldername under my web application? - without quoting the whole path.
2) One problem occurs, that the image does not update immediately so I have only press the refresh button of my browser to see the new chart. How can I solve this problem? - do you mean that with your last sentence? - Unfortunately I do not know exaclty how I can interpret and implement your last sentence correctly.
Please help me once more.
kind regards
You may find the following useful:
String fileSep = System.getProperty("file.separator");
The above line gets the file seperator, \ on windows and / on linux, worth using this in case you port to different operating systems.
String userDir = System.getProperty("user.dir");
will get the current working directory
File myRoot = new File(System.getProperty("user.dir"));
creates a file object for the current working directory
File parent = new File (myRoot.getParent());
Moves one directory up from myRoot
File parent2 = new File (parent.getParent() + fileSep + "configfiles");
moves up another level, then back down to a folder called configfiles
Ref point 2, I havent got round to doing this myself yet, but I had assumed that the code would run in order, so if the image thing ran first it would be there in time.
Have you tried giving the code that creates the image a return value, a boolean would be normal, something like
public boolean createImage()
{
// create my chart
return true
}
in your jsp you could try
if (createImage() = true)
{
// load my image
}
else
{
// output a message telling user to reload, or reload automatically. If you reload automatically, make sure you only do it a set number of times or you will put your users in a very annoying enless loop !!
}
Using the if statement should force the jsp to wait for the image code to execute before moving on.
You could also try programming a delay of a few seconds, but this wouldnt be very reliable.
Post back when you solve it, as I will be doing the same stuff in a couple of weeks.
Hello,
okay thank you very much, one last question:
How can I easily reload the JSP-Site?
regards
pat
PS: The thing with your samples for the current working directory does not work as expected because it is a web application and with this samples it returns every time a path with the jboss directory.
1. What's the problem with cewolf ? I am intersted because we propose to use it in a project.
2. You are right wrt using the samples posted by angrycat for file/directory path info wouldnt work too well in a web application - use the getRealPath(String virtualPath) method of the ServletContext object.
Javadoc below
getRealPath
public java.lang.String getRealPath(java.lang.String path)
Returns a String containing the real path for a given virtual path. For example, the
path "/index.html" returns the absolute file path on the server's filesystem would be served by a request
for "http://host/contextPath/index.html", where contextPath is the context path of this ServletContext.
The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including
the proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason
(such as when the content is being made available from a .war archive).
cheers,
ram.
> 1. What's the problem with cewolf ? I am intersted
> because we propose to use it in a project.
>
To expand, I found that while cewolf has severe limitations, many of them could be overcome by making it work in tandem with the jfreechart apis.
Having said that, I am keeping options as I dont know when I will be running into an unsurpassable limitation ;)
Here's a link that you would find intersting http://homepage.ntlworld.com/richard_c_atkinson/jfreechart/
There is a war file which when deployed has a servlet generating graphs for a web application - you will, ofcourse have to browse the accompanying source code to find out how its done - all the best :)
cheers,
ram.
Hello,
I already want to write the same as you..:) I do not use CeWolf because it has some limitations in comparison to JFreeChart. I have already tested CeWolf and also your quoted example it works well but I didn't find an option to display the item values at the lines of the line chart. Have you found something? (this option would be very important for me and as I have not found it I used JFreeChart)- in JFreeChart there is a method setItemValueVisible or something like that. But I have not found anything similar in the CeWolf Api. Is it possible to display the item values of the lines in the chart?
Unfortunately one more question beside the above one:
What statement do I have to use to reload a JSP-Site?
Regards
pat
Iam not sure about your first question - do you mean the datapoints plotted along the x and y axis ? If yes, they are taken from the Dataset from which the graph is finally drawn (though I am yet to find a way to control their font :))
The problem with cewolf is that it lacks good documentation. However remember that its just a functionality built on top of JFreeChart.
Theorotically anything that you do with JFreeChart can be done using cewolf too - you have to delve into the apis and work on a trial and error method
For example, I was experimenting with overlaid charts. I had one x-y chart (a timeseries chart) and then I had to draw several grid lines (lines parallel to the x-axis).
I found that, with cewolf these lines appeared in a seemingly predefined color. Try as I might, I couldnt change the color of the grid lines.
Finally, after a lot of trial and error and browsing through the apis, I got it working - I used a lot of jFreechart apis to do this work.
public class ColorProcessor implements ChartPostProcessor {
public void processChart(Object arg0, Map params) {
JFreeChart chart = (JFreeChart)arg0;
XYPlot plot = chart.getXYPlot();
DateAxis axis = (DateAxis)plot.getDomainAxis();
axis.setDateFormatOverride(new SimpleDateFormat("H:m:s"));
setColor(plot, params);
}
private void setColor(XYPlot plot, Map params){
for(int i = 0 ; i < plot.getDatasetCount(); i++){
TimeSeriesCollection dataset = (TimeSeriesCollection)plot.getDataset(i);
XYItemRenderer renderer = plot.getRendererForDataset(dataset);
String color = (String)params.get(dataset.getGroup().getID());
renderer.setPaint(Color.decode(color));
}
}
}
Dont worry much about what the code does - just notice that most of the Objects - Plot, XYItemrenderer, DateAxis etc are from jFreeChart - what is important is to get to know how to use this from within your code that generates charts using cewolf.
Anyways, do let me know how you get along.
With regards to reloading jsps, do you mean an auto-refresh ?. You can use the meta tags to auto refresh the page. The below code would cause the browser to refresh the page every 60 seconds.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="refresh" content="60">
</head>
<body>........
Hope that helps,
Ram.
Hello,
1) I mean the setItemLabelsVisible(true); method - with the help of this method the value of each certain point on the line in the line chart will be displayed. And I do not know how to use this method with CeWolf. I used the folowing example:
public class PageViewCountData implements DatasetProducer, CategoryToolTipGenerator, CategoryItemLinkGenerator, Serializable {
private static final Log log = LogFactory.getLog(PageViewCountData.class);
// These values would normally not be hard coded but produced by
// some kind of data source like a database or a file
private final String[] categories ={"mon", "tue", "wen", "thu", "fri", "sat", "sun"};
private final String[] seriesNames ={"cewolfset.jsp", "tutorial.jsp", "testpage.jsp", "performancetest.jsp"};
/**
* Produces some random data.
*/
public Object produceDataset(Map params) throws DatasetProduceException {
log.debug("producing data.");
DefaultCategoryDataset dataset = new DefaultCategoryDataset(){
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this +" finalized.");
}
};
for (int series = 0; series < seriesNames.length; series ++) {
int lastY = (int)(Math.random() * 1000 + 1000);
for (int i = 0; i < categories.length; i++) {
final int y = lastY + (int)(Math.random() * 200 - 100);
lastY = y;
dataset.addValue(y, seriesNames[series], categories);
}
}
return dataset;
}
/**
* This producer's data is invalidated after 5 seconds. By this method the
* producer can influence Cewolf's caching behaviour the way it wants to.
*/
public boolean hasExpired(Map params, Date since) {
log.debug(getClass().getName() + "hasExpired()");
return (System.currentTimeMillis() - since.getTime()) > 5000;
}
/**
* Returns a unique ID for this DatasetProducer
*/
public String getProducerId() {
return "PageViewCountData DatasetProducer";
}
/**
* Returns a link target for a special data item.
*/
public String generateLink(Object data, int series, Object category) {
return seriesNames[series];
}
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this + " finalized.");
}
/**
* @see org.jfree.chart.tooltips.CategoryToolTipGenerator#generateToolTip(CategoryDataset, int, int)
*/
public String generateToolTip(CategoryDataset arg0, int series, int arg2) {
return seriesNames[series];
}
}
And the in the jsp-site:
<jsp:useBean id="pageViews" class="de.laures.cewolf.example.PageViewCountData"/>
<cewolf:chart
id="line"
title="Page View Statistics"
type="line"
xaxislabel="Page"
yaxislabel="Views">
<cewolf:data>
<cewolf:producer id="pageViews"/>
</cewolf:data>
</cewolf:chart>
<cewolf:img chartid="line" renderer="cewolf" width="400" height="300"/>
<P>
But in the PageViewCountData class will not be created a JFreeChart object, so I do not know how I can use the setItemLabelsVisible to display the values of the item. Do you know how I can solve this problem?
2) The refresh of the jsp-site should be done after the jsp-site is called and displayed and only one time. Is this possible?
regards
pat
Hello,
(Second trial:)
1) I mean the setItemLabelsVisible(true); method - with the help of this method the value of each certain point on the line in the line chart will be displayed. And I do not know how to use this method with CeWolf. I used the folowing example:
public class PageViewCountData implements DatasetProducer, CategoryToolTipGenerator, CategoryItemLinkGenerator, Serializable {
private static final Log log = LogFactory.getLog(PageViewCountData.class);
// These values would normally not be hard coded but produced by
// some kind of data source like a database or a file
private final String[] categories ={"mon", "tue", "wen", "thu", "fri", "sat", "sun"};
private final String[] seriesNames ={"cewolfset.jsp", "tutorial.jsp", "testpage.jsp", "performancetest.jsp"};
/**
* Produces some random data.
*/
public Object produceDataset(Map params) throws DatasetProduceException {
log.debug("producing data.");
DefaultCategoryDataset dataset = new DefaultCategoryDataset(){
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this +" finalized.");
}
};
for (int series = 0; series < seriesNames.length; series ++) {
int lastY = (int)(Math.random() * 1000 + 1000);
for (int i = 0; i < categories.length; i++) {
final int y = lastY + (int)(Math.random() * 200 - 100);
lastY = y;
dataset.addValue(y, seriesNames[series], categories);
}
}
return dataset;
}
/**
* This producer's data is invalidated after 5 seconds. By this method the
* producer can influence Cewolf's caching behaviour the way it wants to.
*/
public boolean hasExpired(Map params, Date since) {
log.debug(getClass().getName() + "hasExpired()");
return (System.currentTimeMillis() - since.getTime()) > 5000;
}
/**
* Returns a unique ID for this DatasetProducer
*/
public String getProducerId() {
return "PageViewCountData DatasetProducer";
}
/**
* Returns a link target for a special data item.
*/
public String generateLink(Object data, int series, Object category) {
return seriesNames[series];
}
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this + " finalized.");
}
/**
* @see org.jfree.chart.tooltips.CategoryToolTipGenerator#generateToolTip(CategoryDataset, int, int)
*/
public String generateToolTip(CategoryDataset arg0, int series, int arg2) {
return seriesNames[series];
}
}
And the in the jsp-site:
<jsp:useBean id="pageViews" class="de.laures.cewolf.example.PageViewCountData"/>
<cewolf:chart
id="line"
title="Page View Statistics"
type="line"
xaxislabel="Page"
yaxislabel="Views">
<cewolf:data>
<cewolf:producer id="pageViews"/>
</cewolf:data>
</cewolf:chart>
<cewolf:img chartid="line" renderer="cewolf" width="400" height="300"/>
<P>
But in the PageViewCountData class will not be created a JFreeChart object, so I do not know how I can use the setItemLabelsVisible to display the values of the item. Do you know how I can solve this problem?
2) The refresh of the jsp-site should be done after the jsp-site is called and displayed and only one time. Is this possible?
regards
pat
Hello,
(sorry, i forgot the code tag):
1) I mean the setItemLabelsVisible(true); method - with the help of this method the value of each certain point on the line in the line chart will be displayed. And I do not know how to use this method with CeWolf. I used the folowing example:
public class PageViewCountData implements DatasetProducer, CategoryToolTipGenerator, CategoryItemLinkGenerator, Serializable {
private static final Log log = LogFactory.getLog(PageViewCountData.class);
// These values would normally not be hard coded but produced by
// some kind of data source like a database or a file
private final String[] categories ={"mon", "tue", "wen", "thu", "fri", "sat", "sun"};
private final String[] seriesNames ={"cewolfset.jsp", "tutorial.jsp", "testpage.jsp", "performancetest.jsp"};
/**
* Produces some random data.
*/
public Object produceDataset(Map params) throws DatasetProduceException {
log.debug("producing data.");
DefaultCategoryDataset dataset = new DefaultCategoryDataset(){
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this +" finalized.");
}
};
for (int series = 0; series < seriesNames.length; series ++) {
int lastY = (int)(Math.random() * 1000 + 1000);
for (int i = 0; i < categories.length; i++) {
final int y = lastY + (int)(Math.random() * 200 - 100);
lastY = y;
dataset.addValue(y, seriesNames[series], categories[i]);
}
}
return dataset;
}
/**
* This producer's data is invalidated after 5 seconds. By this method the
* producer can influence Cewolf's caching behaviour the way it wants to.
*/
public boolean hasExpired(Map params, Date since) {
log.debug(getClass().getName() + "hasExpired()");
return (System.currentTimeMillis() - since.getTime()) > 5000;
}
/**
* Returns a unique ID for this DatasetProducer
*/
public String getProducerId() {
return "PageViewCountData DatasetProducer";
}
/**
* Returns a link target for a special data item.
*/
public String generateLink(Object data, int series, Object category) {
return seriesNames[series];
}
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this + " finalized.");
}
/**
* @see org.jfree.chart.tooltips.CategoryToolTipGenerator#generateToolTip(CategoryDataset, int, int)
*/
public String generateToolTip(CategoryDataset arg0, int series, int arg2) {
return seriesNames[series];
}
}
And the in the jsp-site:
<jsp:useBean id="pageViews" class="de.laures.cewolf.example.PageViewCountData"/>
<cewolf:chart
id="line"
title="Page View Statistics"
type="line"
xaxislabel="Page"
yaxislabel="Views">
<cewolf:data>
<cewolf:producer id="pageViews"/>
</cewolf:data>
</cewolf:chart>
<cewolf:img chartid="line" renderer="cewolf" width="400" height="300"/>
<P>
But in the PageViewCountData class will not be created a JFreeChart object, so I do not know how I can use the setItemLabelsVisible to display the values of the item. Do you know how I can solve this problem?
2) The refresh of the jsp-site should be done after the jsp-site is called and displayed and only one time. Is this possible?
regards
pat
I was not aware of cewolf, if the only advantage is that it streams direct to the client as opposed to saving a file on the server, I would have thought it would be easy enough to modify the jFree Chart code to do this.
You could use a method from the cewolf source without too much modification.
Useful thread this is :-)
2. You are right wrt using the samples posted by
angrycat for file/directory path info wouldnt work
too well in a web application - use the
getRealPath(String virtualPath) method of the
ServletContext object.
I had this problem myself but just adjusted the path for the web-app, it works ok but will give java.lang.String getRealPath(java.lang.String path) a go later today, much neater way of doing things.
Thanks;
>I mean the setItemLabelsVisible(true); method - with the help of this >method the value of each certain point on the line in the line chart will >be displayed. And I do not know how to use this method with CeWolf. I >used the folowing example:
Please take a moment to go through the literature in my earlier post - specifically this - what is important is to get to know how to use this from within your code that generates charts using cewolf.
cewolf has a mechanism by which you could alter the graph characteristics - and that is the ChartPostProcessor tag and interface.
You would include the tag inside a chart element. See below
<%@taglib uri='/tags/cewolfTag' prefix='cewolf' %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:useBean id = "graph" class="com.wex.graphpoc.web.handler2.DataProvider" scope="page" />
<cewolf:chart id="grh" title="All" type="xy" xaxislabel="Time(in seconds)" yaxislabel="Average Response Time (in ms)" showlegend = "false">
<cewolf:data>
<cewolf:producer id="graph"/>
</cewolf:data>
<cewolf:chartpostprocessor id="graph">
<cewolf:param name="0" value='<%= "#60" %>'/>
</cewolf:chartpostprocessor>
</cewolf:chart>
<cewolf:img chartid="grh" renderer="/cewolf" width="500" height="400"/>
And then you should have a class implementing the ChartPostProcessor interface.
package com.wex.graphpoc.web.handler2;
import de.laures.cewolf.ChartPostProcessor;
public class ColorProcessor implements ChartPostProcessor {
public void processChart(Object arg0, Map params) {
//the chart object and the params in your chartpostprocessor tag are paassed here.
//work with jfreechart apis to customize your chart
}
}
Specific to your question, you should tell me which class has the method you were speaking about - setItemLabelsVisible()
Thanks,
Ram.
angrycat,
if you have an application that uses charts and you have jfreecharts working, then recommend stick to it. And yes, please be around in the days to come coz I would most probably turn to you/this forum for all clarifications :)
ram.
ps: I am going home now and may not be online for next 10 hours or so