Jump to content

How to skip printing some of the labels?


leeyuiwah

Recommended Posts

Hi,

I want to make a stacked bar with the X-axis value from a time
series.  I learned that there is no stacked (bar or area) time series,
so I decided to use a vanilla stackedArea, and just assign the
"Category expression" so that it take values from a time field.  (By the way, the
two names "series expression" and "category expression" seem inverted
to me -- it took me a long time to find out what each of them actually
means)

However, the plot is not pretty, because I have too many data points
(see the attached image).

So I thought maybe I should write the label expression in such a way
that a string is displayed only a few other lines.  Is there a way to
do that?

I tried several methods to no avail:

1. I set the label expression to (see Code Listing 1) use the
   deprecated getMinutes() method of a java.util.Date object

2. I then tried using a java.util.Calendar object, this object has to
   be calculated for every row in the data set, and I don't know how
   to do that.  The constructor of java.util.Calendar does not take
   the time value; instead, one must get an instance by a
   getInstance() static method, and then use the setTimeInMillis()
   method to set the time value.  This latter method returns void.
   None of the "Calculation Type" -- "Nothing", "Sum", "Average",
   "First" seems to be appropriate.  Also I also tried setting the
   time in the "label expression", that also did not work.  I think I
   can not execute more than one java statement in the "label
   expression", can I? (See Code Listing 2) (And in java there is no
   "common operator" that let you link two statements together)

I am stuck now.  Any ideas will be appreciated.

Clement
 

Code:
Code Listing 1$V{createtime_java_util_Date}.getMinutes()==0) ? $V{createtime_java_util_Date}.toLocaleString() : ""Code Listing 2$V{createtime_java_util_Calendar}.setTimeInMillis($F{createtime}.longValue()*1000); ($V{createtime_java_util_Calendar}.get( Calendar.MINUTES )==0) ? $V{createtime_java_util_Date}.toLocaleString() : ""
Link to comment
Share on other sites

  • Replies 4
  • Created
  • Last Reply

Top Posters In This Topic

I just had to do that for a client, but they own the code so I can't post it.  I can tell you what I did though.

 

Basically, you have to create a time based stacked area chart, then change the type of the x-axis to a time period axis.  This involves writing a chart customizer that makes some pretty big changes to the underlying JFreeChart.  It might be possible to do this via the new component or chart theme API in 3.1, but I was working with the 3.0.

 

You want the area chart to be time based, so you have to author the report using a time series chart.  Don't worry that a time series chart in JasperReports is a line chart, as your customizer will change it.  This way your customizer gets a nice time based data set, and you can set the usual timePeriodExpression in the jrxml.

 

The first thing your customizer has to do is convert the data set - JFreeChart requires a TimeTableXYDataset for stacked area charts, and JasperReports will have created the chart using a TimeSeriesCollection.  You can get the TimeSeriesCollection by calling chart.getPlot().getDataset() on the chart passed in to the customizer.  You create a new TimeTableXYDataset.  Then for each series in the original dataset loop through all the items in the series.  Add a new entry to your dataset using the period, value and key of the original item.

 

Set the dataset in the chart's plot to the one you just created.  Create a StackedXYAreaRender2, and set that in the plot.  To avoid some JFreeChart issues set the plot's dataset rendering order and series rendering order to FORWARD.

 

Finally, create a PeriodAxis, set the date intervals as appropriate for you chart, and then set that as the domain axis in the plot.

 

I strongly recommend getting the JFreeChart documentation before trying this.  Its tricky, but when done you get a chart like the one attached.  It contains 30 days worth of data collected hourly, and the date axis is still readable.



Post Edited by Barry Klawans at 12/19/08 20:05
Link to comment
Share on other sites

  • 2 years later...

Hi,

your replies are very interesting. Thank you for that.

I've followed your guidelines writing my customize method like this:

 

              JRChartPlot plot = jasperChart.getPlot();

//dataset timeseries
JRFillTimeSeriesPlot  myPlot = (JRFillTimeSeriesPlot)plot;
JRFillTimeSeriesDataset inputDataSet = (JRFillTimeSeriesDataset)myPlot.getChart().getDataset();
JRTimeSeries[] timeSeriesArray = inputDataSet.getSeries();
System.out.println(inputDataSet.getSeries().length);
 
 
 
i ve refer to a time series graph with 3 series (lines), but it prints on console just 1 serie.
Debugging the code i see that the methot getSeries does not return the whole series but just one, all the others fields of JRFillTimeSeriesDataset object are private and so inaccesible.
 
How could i loop throgh them??
 
Thank you
Link to comment
Share on other sites

 ah! i've found my error: the customize method has this signature:

 public void customize(JFreeChart jFreeChart, JRChart jasperChart) 

 

I've used jasperChart, while jFreeChart reference must be used. Anyway, this is the piece of code.

Now i'm facing with Period axis to set a specific interval of time, because now it prints a random interval series

Code:
public void customize(JFreeChart jFreeChart, JRChart jasperChart) {		Plot plot = jFreeChart.getPlot();		XYPlot   myPlot = (XYPlot)plot;				//dataset timeseries		TimeSeriesCollection  inputDataSet = (TimeSeriesCollection )myPlot.getDataset();						//dataset per stacked area graph		TimeTableXYDataset ti = new TimeTableXYDataset();				List seriesList = inputDataSet.getSeries();		//loop through series items to copy to other dataset: TimeTableXYDataset		 Iterator it = seriesList.iterator();		    while (it.hasNext()) {		    	TimeSeries serie = (TimeSeries)it.next();		        		        int itemCount = serie.getItemCount();		        		        for(int i =0; i<itemCount; i++)		        {				        	//add serie to other dataset		        	ti.add(serie.getTimePeriod(i), serie.getValue(i), (String)serie.getKey(), false);		        	 		        }		       		    }		 				//stacked area render to draw the correct graph		    		   		StackedXYAreaRenderer2  s = new StackedXYAreaRenderer2();		myPlot.setDataset(ti);		myPlot.setRenderer(s);		myPlot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);		myPlot.setSeriesRenderingOrder(SeriesRenderingOrder.FORWARD);				//axis formatter		PeriodAxis p = new PeriodAxis("");//		p.setAutoRangeTimePeriodClass(Day.class);//		p.setMajorTickTimePeriodClass(Minute.class);		p.setFixedAutoRange(new Double("12.4"));		PeriodAxisLabelInfo[] info = new PeriodAxisLabelInfo[2];				info[0] = new PeriodAxisLabelInfo(Minute.class, new SimpleDateFormat("hh:mm"));		 //	       info[1] = new PeriodAxisLabelInfo(Year.class, new SimpleDateFormat("yyyy"));	    info[1] = new PeriodAxisLabelInfo(Day.class,  new SimpleDateFormat("dd-MMM-yyyy"));		p.setLabelInfo(info);		myPlot.setDomainAxis(p);					}
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...