Hello,
We have built a graphing application using cewolf. It allows the user to select a set of attributes and a time range to graph statistics data. Since it is user driven the amount of data will grow as the time or number of selected attributes increases. Using Mozilla we have not seen a limitation to display the data (besides that a larger set takes longer to graph). However in Internet Explorer at certain number of data points (which varies depending on the machine used and the data set values) the browser is unable to display the graph. When this point is reached the browser looses all images and looses font information.
We have contacted Microsoft support and they have concluded that the problem is the way the application is graphing the results. This is making an exesive use of GDI objects in the machine and it eventually runs out of memory to process the graph.
Given the broad usage of cewolf I was wondering if any of the users have experienced this problem before and how has been addressed.

Thanks,
Maria

The jsp that we use to generate the graph is:

.....

<cewolf:overlaidchart 
id="line" 
title="" 
type="overlaidxy" 
xaxistype="date"
yaxistype="number"
xaxislabel="Time" 
yaxislabel="Values"
showlegend="false" >
<cewolf:plot type="<%=graphType%>">
<cewolf:data>
<cewolf:producer id="timeData" />
</cewolf:data>
</cewolf:plot>
<cewolf:colorpaint color="#FFFFFF"/>

<cewolf:chartpostprocessor id="timeData" />

</cewolf:overlaidchart>

<p>

<cewolf:img chartid="line" renderer="cewolf" width="700" height="400">
<cewolf:map linkgeneratorid="timeData" tooltipgeneratorid="timeData" />
</cewolf:img>

<cewolf:legend renderer="cewolf" id="line" border="1" width="700" height="<%=timeLegendHeight%>">
</cewolf:legend>

<br>

<P>

.....

The DataGraphProducer is as follows:
//-----------------------------------
// ** Package **
//-----------------------------------

package exodus.jstatsmon;

import java.io.Serializable;
import java.util.*;
import java.text.*;
import java.math.BigDecimal;

import exodus.jflags.*;

import org.jfree.data.category.*;
import org.jfree.data.time.*;
import org.jfree.data.xy.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.*;
import org.jfree.chart.renderer.xy.*;
import org.jfree.chart.axis.*;

import de.laures.cewolf.*;
import de.laures.cewolf.links.*;
import de.laures.cewolf.tooltips.*;

public class JStatsDataGraphProducer implements DatasetProducer, XYToolTipGenerator, XYItemLinkGenerator , ChartPostProcessor, Serializable 
{
private static TraceFlag graphProducerTF = new TraceFlag("graphProducerTF");

private JStatsSession sessionObj;
private DataGraph dataGraph;
private HashMap nameAssignmentById = new HashMap();
private TimeSeriesCollection dataSet;

//
// Need to get the queries and their results to display
// in the graph
//
public final void setDataGraph( DataGraph dataGraph)
{
this.dataGraph = dataGraph;
}

public final void setSessionRef(JStatsSession session)
{
sessionObj = session;
}

//
// Main method used by cewolf to get the datasets
//
public Object produceDataset(Map params) 
throws DatasetProduceException 
{

graphProducerTF.exoTraceLevel(1, "JStatsDataGraphProducer: creating dataSeries for cewolf");

dataSet = new TimeSeriesCollection();
SimpleDateFormat sdf = new SimpleDateFormat(JStatsConsts.ParsingDateFormat, Locale.US);

ArrayList queryList = dataGraph.getQueryList();
Query tmpQuery = null;
String[] attributes = null;
String seriesName;
String uniqueName;
ArrayList currentSeries = new ArrayList();
int counter = 0; // Number of series

try
{
for (int i = 0; i < queryList.size(); i++)
{
tmpQuery = (Query) queryList.get(i);

//
// We cannot graph no numeric values...
// These queries that we skip here are presented as tables.
// 
if (tmpQuery.hasNoNumeric()) 
{
continue;
}

if (tmpQuery.hasNoTimeAxis())
{
//
// This is a no timeBased query. Not handled in this DataSet producer.
//
continue;
}

graphProducerTF.exoTraceLevel(2, "JStatsDataGraphProducer: Getting results for " + 
tmpQuery.getUniqueName());

ArrayList results = tmpQuery.getResults();
if (results == null)
{
//
// There is no data to create dataSet.
//
graphProducerTF.exoTraceLevel(2, "JStatsDataGraphProducer: Query " + 
tmpQuery.getUniqueName() + " has no data ");
continue;
}
attributes = tmpQuery.getAttributes();
TimeSeries series = null;
String[] values;
uniqueName = tmpQuery.getUniqueName();
int records = 0;
for (int k = 0 ; k < attributes.length ; k++)
{
String tmpAttr = sessionObj.getLogSchema().getAttributeDisplayName(tmpQuery.getTypeName(), tmpQuery.getDataSetName(),attributes[k]);
seriesName = uniqueName + ":" + tmpAttr;
series = new TimeSeries(seriesName,FixedMillisecond.class);
records = results.size();
graphProducerTF.exoTraceLevel(2, "JStatsDataGraphProducer: Query "+ 
tmpQuery.getUniqueName() + " has " + records + " results");

for (int j = 0 ; j < records; j++)

values = (String[]) results.get(j);
if (values[k+1] != null)
{
if (values[k+1].indexOf(".") < 0)
{
Long longValue = new Long(values[k+1]);
series.addOrUpdate(new FixedMillisecond(sdf.parse(values[0])), longValue.doubleValue());
}
else
{
Double dValue = new Double(values[k+1]);
series.addOrUpdate(new FixedMillisecond(sdf.parse(values[0])), dValue.doubleValue());
}
}
}
if (records>0) 
{
dataSet.addSeries(series);
sessionObj.assignColor(seriesName,counter);
currentSeries.add(seriesName);
nameAssignmentById.put(new Integer(counter), seriesName);
counter++;
}
}
}
//
// Got all data for graph. Set update to false. Will not re-read
// this data until the graph has new data.
// 
dataGraph.setUpdated(false);
//
// Release colors assigned to attributes that are not longer
// displayed in the graph.
//
sessionObj.releaseColors(currentSeries);

graphProducerTF.exoTraceLevel(1, "JStatsDataGraphProducer: FInished creating dataSeries for cewolf");
return dataSet;
}
catch (ParseException ex)
{
throw new DatasetProduceException(ex.toString());
}
}

public final boolean hasExpired(Map params, Date since) { 
return dataGraph.getUpdated();
}

public final String getProducerId() {
return "JStatsmon DatasetProducer";
}

//
// Required to generate tool-tip
//
public String generateToolTip(XYDataset data, int series, int item) 
{
SimpleDateFormat dateformat = new SimpleDateFormat(JStatsConsts.DisplayDateFormat);
Date d = new Date(((Long)data.getX(series,item)).longValue());
String seriesName = (String) nameAssignmentById.get(new Integer(series));

String yValue = "" + data.getY(series,item);
if (yValue.indexOf(".0") >= 0)
{
yValue = yValue.substring(0, yValue.indexOf("."));
}
return seriesName +":::Time=" + dateformat.format(d) + ":::Value="+ yValue;
}

//
// The link associated to a point in the graph
//
public String generateLink(Object data, int series, int item) 
{
//
// This date format is expected in the javascript function to change
// time window: "06/12/05 13:02:34"
//
SimpleDateFormat dateformat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
XYDataset dataset = (XYDataset) data;
Date d = new Date(((Long)dataset.getX(series,item)).longValue()); 
return "javascript:changeTime('" + dateformat.format(d) + "')";
}

//
// This is required to change the colors of the series and apply
// other post processing to the graph. 
// This is the way I currently have found to access jfreechart features for graph
// manipulation.
//
public void processChart(Object chart, Map params) {

graphProducerTF.exoTraceLevel(1, "JStatsDataGraphProducer: postProcessing the chart");

XYPlot plot = ((JFreeChart) chart).getXYPlot();
XYItemRenderer renderer = plot.getRenderer(0);

for (int i = 0; i < dataSet.getSeriesCount() ; i++)
{
renderer.setSeriesPaint(i, java.awt.Color.decode(sessionObj.getColorAssignedForIndex(i)));
}

//
// Set the range for the graph, do not include zero if not necesary.
//
((NumberAxis) plot.getRangeAxis()).setAutoRangeIncludesZero(false);

}

}