001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.tag;
020
021import java.awt.Color;
022import java.awt.Font;
023import java.awt.GradientPaint;
024import java.awt.Rectangle;
025import java.awt.image.BufferedImage;
026import java.io.ByteArrayOutputStream;
027import java.io.IOException;
028import java.io.OutputStream;
029import java.io.Serializable;
030import java.util.ArrayList;
031import java.util.Collections;
032import java.util.Iterator;
033import java.util.List;
034import java.util.TimeZone;
035
036import lucee.commons.color.ColorCaster;
037import lucee.commons.io.IOUtil;
038import lucee.commons.io.res.Resource;
039import lucee.commons.io.res.util.ResourceUtil;
040import lucee.commons.lang.Md5;
041import lucee.commons.lang.StringUtil;
042import lucee.runtime.chart.BarRenderer3DWrap;
043import lucee.runtime.chart.CategoryToolTipGeneratorImpl;
044import lucee.runtime.chart.LabelFormatUtil;
045import lucee.runtime.chart.PieSectionLabelGeneratorImpl;
046import lucee.runtime.chart.PieSectionLegendLabelGeneratorImpl;
047import lucee.runtime.chart.PieToolTipGeneratorImpl;
048import lucee.runtime.chart.TickUnitsImpl;
049import lucee.runtime.converter.JavaConverter;
050import lucee.runtime.engine.ThreadLocalPageContext;
051import lucee.runtime.exp.ApplicationException;
052import lucee.runtime.exp.ExpressionException;
053import lucee.runtime.exp.PageException;
054import lucee.runtime.ext.tag.BodyTagImpl;
055import lucee.runtime.functions.dateTime.DateAdd;
056import lucee.runtime.img.Image;
057import lucee.runtime.op.Caster;
058import lucee.runtime.op.date.DateCaster;
059import lucee.runtime.type.dt.DateTime;
060
061import org.jfree.chart.ChartFactory;
062import org.jfree.chart.ChartRenderingInfo;
063import org.jfree.chart.ChartUtilities;
064import org.jfree.chart.JFreeChart;
065import org.jfree.chart.axis.Axis;
066import org.jfree.chart.axis.AxisLocation;
067import org.jfree.chart.axis.CategoryAxis;
068import org.jfree.chart.axis.CategoryLabelPositions;
069import org.jfree.chart.axis.SymbolAxis;
070import org.jfree.chart.axis.ValueAxis;
071import org.jfree.chart.block.ColumnArrangement;
072import org.jfree.chart.block.LineBorder;
073import org.jfree.chart.plot.CategoryPlot;
074import org.jfree.chart.plot.PiePlot;
075import org.jfree.chart.plot.PiePlot3D;
076import org.jfree.chart.plot.Plot;
077import org.jfree.chart.plot.PlotOrientation;
078import org.jfree.chart.plot.XYPlot;
079import org.jfree.chart.renderer.category.BarRenderer3D;
080import org.jfree.chart.renderer.category.CategoryItemRenderer;
081import org.jfree.chart.renderer.category.LineAndShapeRenderer;
082import org.jfree.chart.renderer.xy.XYItemRenderer;
083import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
084import org.jfree.chart.title.LegendTitle;
085import org.jfree.chart.title.TextTitle;
086import org.jfree.chart.urls.PieURLGenerator;
087import org.jfree.chart.urls.StandardCategoryURLGenerator;
088import org.jfree.chart.urls.StandardXYURLGenerator;
089import org.jfree.chart.urls.URLUtilities;
090import org.jfree.data.Range;
091import org.jfree.data.category.CategoryDataset;
092import org.jfree.data.category.DefaultCategoryDataset;
093import org.jfree.data.general.DefaultPieDataset;
094import org.jfree.data.general.PieDataset;
095import org.jfree.data.time.Second;
096import org.jfree.data.time.TimeSeries;
097import org.jfree.data.time.TimeSeriesCollection;
098import org.jfree.data.xy.XYDataset;
099import org.jfree.data.xy.XYSeries;
100import org.jfree.data.xy.XYSeriesCollection;
101import org.jfree.ui.HorizontalAlignment;
102import org.jfree.ui.RectangleAnchor;
103import org.jfree.ui.RectangleEdge;
104import org.jfree.ui.RectangleInsets;
105import org.jfree.util.ShapeUtilities;
106
107
108public final class Chart extends BodyTagImpl implements Serializable {
109
110        
111        
112        public static final Color COLOR_999999=new Color(0x99,0x99,0x99);
113        public static final Color COLOR_666666=new Color(0x66,0x66,0x66);
114        public static final Color COLOR_333333=new Color(0x33,0x33,0x33);
115        
116        public static final String FONT_ARIAL = "arial";
117        public static final String FONT_TIMES = "times";
118        public static final String FONT_COURIER = "courier";
119        public static final String FONT_ARIAL_UNICODE_MS = "arialunicodems";
120
121        public static final int FORMAT_GIF = 0;
122        public static final int FORMAT_JPG = 1;
123        public static final int FORMAT_PNG = 2;
124        public static final int FORMAT_FLASH=3;
125
126
127        public static final int PIE_SLICE_STYLE_SOLID = 0;
128        public static final int PIE_SLICE_STYLE_SLICED = 1;
129        
130        public static final int SERIES_PLACEMENT_DEFAULT = 0;
131        public static final int SERIES_PLACEMENT_CLUSTER = 1;
132        public static final int SERIES_PLACEMENT_STACKED = 2;
133        public static final int SERIES_PLACEMENT_PERCENT = 3;
134
135        public static final int TIP_STYLE_NONE = 0;
136        public static final int TIP_STYLE_FORMATS = 1;
137        public static final int TIP_STYLE_MOUSEDOWN = 2;
138        public static final int TIP_STYLE_MOUSEOVER = 3;
139        
140        public static final CategoryLabelPositions LABEL_HORIZONTAL = CategoryLabelPositions.STANDARD;
141        public static final CategoryLabelPositions LABEL_VERTICAL = CategoryLabelPositions.DOWN_90;
142        public static final CategoryLabelPositions LABEL_DOWN_90 = CategoryLabelPositions.DOWN_90;
143        public static final CategoryLabelPositions LABEL_DOWN_45 = CategoryLabelPositions.DOWN_45;
144        public static final CategoryLabelPositions LABEL_UP_45 = CategoryLabelPositions.UP_45;
145        public static final CategoryLabelPositions LABEL_UP_90 = CategoryLabelPositions.UP_90;
146
147        private static final int NONE = 0;
148        private static final int YES = 1;
149        private static final int NO = 2;
150        
151
152        private static int chartIndex=0;
153        
154        private Color backgroundcolor=Color.WHITE;
155        private Color databackgroundcolor=Color.WHITE;
156        private Color foregroundcolor=Color.BLACK;
157        private Color tipbgcolor=Color.WHITE;
158        private String xaxistitle=null;
159        private String yaxistitle=null;
160        
161
162        private int chartheight=240;
163        private int chartwidth=320;
164        
165        private String font=FONT_ARIAL;
166        private int fontstyle=0;
167        private int fontsize=11;
168        
169        private int format=FORMAT_PNG;
170        private int gridlines=10;
171        
172        private int labelFormat=LabelFormatUtil.LABEL_FORMAT_NUMBER;
173        private CategoryLabelPositions labelPosition=LABEL_HORIZONTAL;
174        private int markersize=-1;
175        
176        private String name=null;
177        
178        private int pieslicestyle=PIE_SLICE_STYLE_SLICED;
179
180        private double scalefrom=Double.NaN;
181        private double scaleto=Double.NaN;
182        private boolean legendMultiLine=false;
183        
184        private int seriesplacement=SERIES_PLACEMENT_DEFAULT;
185
186        private boolean show3d=false;
187        private boolean showtooltip=true;
188        private boolean showborder=false;
189        private boolean showlegend=true;
190        private boolean showmarkers=true;
191        private int showxgridlines=NONE;
192        private boolean showygridlines=false;
193        private boolean sortxaxis=false;
194
195        private String style=null;
196        private String title="";
197        
198        private int tipstyle=TIP_STYLE_MOUSEOVER;
199        private List<ChartSeriesBean> _series=new ArrayList<ChartSeriesBean>();
200
201        private String url;
202        private double xoffset=0.1;
203        private double yoffset=0.1;
204        private String xaxistype="category";
205        private String yaxistype="category";
206        private double smallest;
207        private double biggest;
208        private boolean showXLabel=true;
209        private String source;
210        private List<String> _plotItemLables = new ArrayList<String>();
211        
212        public void release() {
213                _series.clear();
214
215                url=null;
216                xoffset=0.1;
217                yoffset=0.1;
218                xaxistype="category";
219                yaxistype="category";
220                                
221                xaxistitle="";
222                yaxistitle="";
223                legendMultiLine=false;
224                // TODO super.release();
225                backgroundcolor=Color.WHITE;
226                databackgroundcolor=Color.WHITE;
227                foregroundcolor=Color.BLACK;
228                tipbgcolor=Color.WHITE;
229                
230                chartheight=240;
231                chartwidth=320;
232                
233                font=FONT_ARIAL;
234                fontstyle=0;
235                fontsize=11;
236                
237                format=FORMAT_PNG;
238                gridlines=10;
239                
240                labelFormat=LabelFormatUtil.LABEL_FORMAT_NUMBER;
241                labelPosition=LABEL_HORIZONTAL;
242
243                markersize=-1;
244                name=null;
245                
246                pieslicestyle=PIE_SLICE_STYLE_SLICED;
247                
248                scalefrom=Double.NaN;
249                scaleto=Double.NaN;
250                seriesplacement=SERIES_PLACEMENT_DEFAULT;
251                
252                show3d=false;
253                showborder=false;
254                showlegend=true;
255                showmarkers=true;
256                showxgridlines=NONE;
257                showygridlines=false;
258                sortxaxis=false;
259                showXLabel=true;
260                showtooltip=true;
261                style=null;
262                title="";
263                source=null;
264                tipstyle=TIP_STYLE_MOUSEOVER;
265                _plotItemLables = new ArrayList<String>();
266        }
267        
268        
269
270        public void setShowxlabel(boolean showXLabel) {
271                this.showXLabel = showXLabel;
272        }
273        public void setCategorylabelpositions(String strOrientation) {
274                strOrientation=strOrientation.trim().toLowerCase();
275                if("vertical".equals(strOrientation))labelPosition=LABEL_VERTICAL;
276                else if("up_45".equals(strOrientation))labelPosition=LABEL_UP_45;
277                else if("up_90".equals(strOrientation))labelPosition=LABEL_UP_90;
278                else if("down_45".equals(strOrientation))labelPosition=LABEL_DOWN_45;
279                else if("down_90".equals(strOrientation))labelPosition=LABEL_DOWN_90;
280                else if("standard".equals(strOrientation))labelPosition=LABEL_HORIZONTAL;
281                else labelPosition=LABEL_HORIZONTAL;
282                //else throw new ExpressionException("invalid value ["+strOrientation+"] for attribute CategoryLabelPositions, for this attribute only the following values are supported [horizontal,vertical,up_90,up_45,down_90,down_45]");
283        }
284        public void setSource(String source) {
285                this.source = source;
286        }
287        public void setShowtooltip(boolean showtooltip) {
288                this.showtooltip = showtooltip;
289        }
290        public void setBackgroundcolor(String strBackgroundColor) throws ExpressionException {
291                this.backgroundcolor = ColorCaster.toColor(strBackgroundColor);
292        }
293        
294        public void setDatabackgroundcolor(String strDatabackgroundcolor) throws ExpressionException {
295                this.databackgroundcolor = ColorCaster.toColor(strDatabackgroundcolor);
296        }
297
298        public void setForegroundcolor(String strForegroundcolor) throws ExpressionException {
299                this.foregroundcolor = ColorCaster.toColor(strForegroundcolor);
300        }
301
302        public void setTipbgcolor(String strTipbgcolor) throws ExpressionException {
303                this.tipbgcolor = ColorCaster.toColor(strTipbgcolor);
304        }
305        
306        public void setChartheight(double chartheight) {
307                this.chartheight = (int) chartheight;
308        }
309
310        public void setChartwidth(double chartwidth) {
311                this.chartwidth = (int) chartwidth;
312        }
313
314        public void setFont(String strFont) {
315                strFont=strFont.trim().toLowerCase();
316                if("arial".equals(strFont))font=FONT_ARIAL;
317                else if("times".equals(strFont))font=FONT_TIMES;
318                else if("courier".equals(strFont))font=FONT_COURIER;
319                else if("arialunicodems".equals(strFont))font=FONT_ARIAL_UNICODE_MS;
320                else font=strFont;
321                //else throw new ExpressionException("invalid value ["+strFont+"] for attribute font, for this attribute only the following values are supported [arial,times,courier,arialunicodeMS]");
322        }
323
324        public void setFontbold(boolean fontbold) {
325                if(fontbold)fontstyle+=Font.BOLD;
326        }
327
328        public void setFontitalic(boolean fontitalic) {
329                if(fontitalic)fontstyle+=Font.ITALIC;
330        }
331
332        public void setFontsize(double fontsize) {
333                this.fontsize = (int) fontsize;
334        }
335
336        public void setFormat(String strFormat) throws ExpressionException {
337                strFormat=strFormat.trim().toLowerCase();
338                if("gif".equals(strFormat))                     format=FORMAT_GIF;
339                else if("jpg".equals(strFormat))        format=FORMAT_JPG;
340                else if("jpeg".equals(strFormat))       format=FORMAT_JPG;
341                else if("jpe".equals(strFormat))        format=FORMAT_JPG;
342                else if("png".equals(strFormat))        format=FORMAT_PNG;
343                //else if("flash".equals(strFormat))    format=FORMAT_FLASH;
344                //else if("swf".equals(strFormat))      format=FORMAT_FLASH;
345                
346                else throw new ExpressionException("invalid value ["+strFormat+"] for attribute format, for this attribute only the following values are supported [gif,jpg,png]");
347        }
348
349        public void setGridlines(double gridlines) {
350                this.gridlines = (int) gridlines;
351        }
352
353        public void setLabelformat(String strLabelFormat) throws ExpressionException {
354                strLabelFormat=strLabelFormat.trim().toLowerCase();
355                if("number".equals(strLabelFormat))                     labelFormat=LabelFormatUtil.LABEL_FORMAT_NUMBER;
356                else if("numeric".equals(strLabelFormat))       labelFormat=LabelFormatUtil.LABEL_FORMAT_NUMBER;
357                else if("currency".equals(strLabelFormat))      labelFormat=LabelFormatUtil.LABEL_FORMAT_CURRENCY;
358                else if("date".equals(strLabelFormat))          labelFormat=LabelFormatUtil.LABEL_FORMAT_DATE;
359                else if("percent".equals(strLabelFormat))       labelFormat=LabelFormatUtil.LABEL_FORMAT_PERCENT;
360                //else if("integer".equals(strLabelFormat))     labelFormat=LabelFormatUtil.LABEL_FORMAT_INTEGER;
361                
362                else throw new ExpressionException("invalid value ["+strLabelFormat+"] for attribute labelFormat, for this attribute only the following values are supported [date,percent,currency,number]");
363        }
364
365        public void setMarkersize(double markersize) throws ExpressionException {
366                if(markersize<1) throw new ExpressionException("invalid value ["+markersize+"] for attribute markersize, value must be a positive integer greater than 0");
367                this.markersize=(int) markersize;
368        }
369
370        public void setName(String name) {
371                this.name = name;
372        }
373
374        public void setPieslicestyle(String strPieslicestyle) throws ExpressionException {
375                strPieslicestyle=strPieslicestyle.trim().toLowerCase();
376                if("sliced".equals(strPieslicestyle))           pieslicestyle=PIE_SLICE_STYLE_SLICED;
377                else if("slice".equals(strPieslicestyle))       pieslicestyle=PIE_SLICE_STYLE_SLICED;
378                else if("solid".equals(strPieslicestyle))       pieslicestyle=PIE_SLICE_STYLE_SOLID;
379                
380                else throw new ExpressionException("invalid value ["+strPieslicestyle+"] for attribute pieSliceStyle, for this attribute only the following values are supported [sliced,solid]");
381        }
382
383        public void setScaleto(double scaleto) {
384                //if(scaleto<0) throw new ExpressionException("invalid value ["+scaleto+"] for attribute scaleto, value must be a positive integer greater or equal than 0");
385                this.scaleto =  scaleto;
386        }
387
388        public void setScalefrom(double scaletrom)  {
389                //if(scaletrom<0) throw new ExpressionException("invalid value ["+scaletrom+"] for attribute scaletrom, value must be a positive integer greater or equal than 0");
390                this.scalefrom =  scaletrom;
391        }
392
393        public void setSeriesplacement(String strSeriesplacement) throws ExpressionException {
394                strSeriesplacement=strSeriesplacement.trim().toLowerCase();
395                if("default".equals(strSeriesplacement))        seriesplacement=SERIES_PLACEMENT_DEFAULT;
396                else if("cluster".equals(strSeriesplacement))seriesplacement=SERIES_PLACEMENT_CLUSTER;
397                else if("stacked".equals(strSeriesplacement))seriesplacement=SERIES_PLACEMENT_STACKED;
398                else if("percent".equals(strSeriesplacement))seriesplacement=SERIES_PLACEMENT_PERCENT;
399                
400                else throw new ExpressionException("invalid value ["+strSeriesplacement+"] for attribute seriesplacement, for this attribute only the following values are supported [default,cluster,percent,stacked]");
401        }
402
403        public void setShow3d(boolean show3d) {
404                this.show3d = show3d;
405        }
406
407        public void setShowborder(boolean showborder) {
408                this.showborder = showborder;
409        }
410
411        public void setShowlegend(boolean showlegend) {
412                this.showlegend = showlegend;
413        }
414
415        public void setShowmarkers(boolean showmarkers) {
416                this.showmarkers = showmarkers;
417        }
418
419        public void setShowxgridlines(boolean showxgridlines) {
420                this.showxgridlines = showxgridlines?YES:NO;
421        }
422
423        public void setShowygridlines(boolean showygridlines) {
424                this.showygridlines = showygridlines;
425        }
426
427        public void setSortxaxis(boolean sortxaxis) {
428                this.sortxaxis = sortxaxis;
429        }
430
431        public void setStyle(String style) {
432                this.style = style;
433        }
434
435        public void setTitle(String title) {
436                this.title = title;
437        }
438
439        public void setTipstyle(String strTipstyle) throws ExpressionException {
440                strTipstyle=strTipstyle.trim().toLowerCase();
441                if("mousedown".equals(strTipstyle))             tipstyle=TIP_STYLE_MOUSEDOWN;
442                else if("mouseover".equals(strTipstyle))tipstyle=TIP_STYLE_MOUSEOVER;
443                else if("none".equals(strTipstyle))             tipstyle=TIP_STYLE_NONE;
444                else if("formats".equals(strTipstyle))  tipstyle=TIP_STYLE_FORMATS;
445                
446                else throw new ExpressionException("invalid value ["+strTipstyle+"] for attribute Tipstyle, for this attribute only the following values are supported [mouseover,mousedown,one,formats]");
447        }
448        
449
450        
451        /**
452         * @param xaxistitle the xaxistitle to set
453         */
454        public void setXaxistitle(String xaxistitle) {
455                this.xaxistitle = xaxistitle;
456        }
457
458        /**
459         * @param yaxistitle the yaxistitle to set
460         */
461        public void setYaxistitle(String yaxistitle) {
462                this.yaxistitle = yaxistitle;
463        }
464
465        public void addChartSeries(ChartSeriesBean series) {
466                _series.add(series);
467        }
468        
469
470        public int doStartTag() {
471                return EVAL_BODY_INCLUDE;
472        }
473
474        @Override
475        public int doEndTag() throws PageException {
476                if(_series.size()==0) throw new ApplicationException("at least one cfchartseries tag required inside cfchart"); 
477                //if(_series.size()>1) throw new ApplicationException("only one cfchartseries tag allowed inside cfchart"); 
478                //doSingleSeries((ChartSeriesBean) _series.get(0));
479                ChartSeriesBean first= _series.get(0);
480                
481                try {
482                                
483                        if(first.getType()==ChartSeriesBean.TYPE_BAR)
484                                //throw new ApplicationException("type bar is not supported");
485                                chartBar();
486                        else if(first.getType()==ChartSeriesBean.TYPE_TIME)
487                                chartTimeLine();
488                        else if(first.getType()==ChartSeriesBean.TYPE_AREA)
489                                chartArea();
490                        else if(first.getType()==ChartSeriesBean.TYPE_CONE)
491                                throw new ApplicationException("type cone is not supported");
492                        else if(first.getType()==ChartSeriesBean.TYPE_CURVE)
493                                chartLine();
494                                //throw new ApplicationException("type curve is not supported");
495                        else if(first.getType()==ChartSeriesBean.TYPE_CYLINDER)
496                                throw new ApplicationException("type cylinder is not supported");
497                        else if(first.getType()==ChartSeriesBean.TYPE_HORIZONTALBAR)
498                                chartHorizontalBar();
499                        else if(first.getType()==ChartSeriesBean.TYPE_LINE)
500                                chartLine();
501                                //throw new ApplicationException("type line is not supported");
502                        else if(first.getType()==ChartSeriesBean.TYPE_PIE)
503                                chartPie();
504                        else if(first.getType()==ChartSeriesBean.TYPE_PYRAMID)
505                                throw new ApplicationException("type pyramid is not supported");
506                        else if(first.getType()==ChartSeriesBean.TYPE_SCATTER)
507                                chartScatter();
508                        else if(first.getType()==ChartSeriesBean.TYPE_STEP)
509                                chartStep();
510                }
511                catch(IOException ioe) {
512                        throw Caster.toPageException(ioe);
513                }
514                
515                return EVAL_PAGE;
516        }
517
518        private void chartPie() throws PageException, IOException {
519                // do dataset
520                DefaultPieDataset dataset = new DefaultPieDataset();
521                ChartSeriesBean csb =  _series.get(0);
522        
523                ChartDataBean cdb;
524        
525                List datas=csb.getDatas();
526                if(sortxaxis)Collections.sort(datas);
527        Iterator itt = datas.iterator();
528        while(itt.hasNext()) {
529                cdb=(ChartDataBean) itt.next();
530                dataset.setValue(cdb.getItemAsString(), cdb.getValue());
531        }       
532                
533        
534        JFreeChart chart = show3d?
535                        ChartFactory.createPieChart3D   (title, dataset, false, true, true):
536                        ChartFactory.createPieChart             (title, dataset, false, true, true);
537        
538        Plot p = chart.getPlot();
539                PiePlot pp = (PiePlot)p;
540        
541                Font _font = getFont();
542        pp.setLegendLabelGenerator(new PieSectionLegendLabelGeneratorImpl(_font,chartwidth));
543        pp.setBaseSectionOutlinePaint(Color.GRAY); // border
544        pp.setLegendItemShape(new Rectangle(7,7));
545        pp.setLabelFont(new Font(font,0,11));
546        pp.setLabelLinkPaint(COLOR_333333);
547        pp.setLabelLinkMargin(-0.05);
548        pp.setInteriorGap(0.123);
549        pp.setLabelGenerator(new PieSectionLabelGeneratorImpl(labelFormat));
550        
551        
552        
553        
554        databackgroundcolor=backgroundcolor;
555        
556        setBackground(chart,p);
557                setBorder(chart,p);
558                setLegend(chart,p,_font);
559                set3d(p);
560                setFont(chart, _font);
561        setTooltip(chart);
562        setScale(chart);
563        
564        // Slice Type and colors
565        boolean doSclice=pieslicestyle==PIE_SLICE_STYLE_SLICED;
566        Color[] colors = csb.getColorlist();
567        Iterator it = csb.getDatas().iterator();
568        int count=0;
569        while(it.hasNext()) {
570                cdb=(ChartDataBean) it.next();
571            if(doSclice)pp.setExplodePercent(cdb.getItemAsString(), 0.13);
572            
573            if(count<colors.length){
574                pp.setSectionPaint(cdb.getItemAsString(), colors[count]);
575            }
576            count++;
577        }
578        
579        writeOut(chart);
580        }
581        
582
583        private void set3d(Plot plot) {
584        if(!show3d) return;
585        
586        plot.setForegroundAlpha(0.6f);
587        
588        if(plot instanceof CategoryPlot) {
589            plot.setForegroundAlpha(0.8f);
590                CategoryPlot cp=(CategoryPlot) plot;
591                CategoryItemRenderer renderer = cp.getRenderer();
592                if(renderer instanceof BarRenderer3D) {
593                        BarRenderer3D br3d=(BarRenderer3D) renderer;
594                        cp.setRenderer(new BarRenderer3DWrap(br3d,xoffset,yoffset));
595                }
596                
597        }
598        else if(plot instanceof PiePlot3D) {
599                PiePlot3D pp3d=(PiePlot3D) plot;
600            pp3d.setDepthFactor(0.10);    
601        }
602        
603        
604
605        //CategoryItemRenderer renderer = plot.getRenderer();
606        
607        }
608
609        private void setFont(JFreeChart chart, Font font) {
610                // title
611                TextTitle title=chart.getTitle();
612                if(title!=null) {
613                        title.setFont(font);
614                        title.setPaint(foregroundcolor);
615                        chart.setTitle(title);
616                }
617                
618                // axis fonts
619                Plot plot = chart.getPlot();
620                if(plot instanceof CategoryPlot) {
621                        CategoryPlot cp = (CategoryPlot)plot;
622                        setAxis(cp.getRangeAxis(),font);
623                        setAxis(cp.getDomainAxis(),font);
624                }
625                if(plot instanceof XYPlot) {
626                        XYPlot cp = (XYPlot)plot;
627                        setAxis(cp.getRangeAxis(),font);
628                        setAxis(cp.getDomainAxis(),font);
629                }
630                
631                
632        }
633        
634        
635        private void setAxis(Axis axis, Font font) {
636                if(axis!=null) {
637                        axis.setLabelFont(font);
638                        axis.setLabelPaint(foregroundcolor);
639                        
640                        axis.setTickLabelFont(font);
641                axis.setTickLabelPaint(foregroundcolor);
642                axis.setTickLabelsVisible(true);
643                }
644        }
645
646
647
648        private void setLegend(JFreeChart chart, Plot plot, Font font) {
649                if(!showlegend) return;
650                        
651                        
652                Color bg = backgroundcolor==null?databackgroundcolor:backgroundcolor;
653                if(font==null)font=getFont();
654                
655                
656                
657                LegendTitle legend = legendMultiLine?
658                        new LegendTitle(plot,new ColumnArrangement(), new ColumnArrangement()):
659                        new LegendTitle(plot);
660        legend.setBackgroundPaint(bg);
661        legend.setMargin(new RectangleInsets(1.0, 1.0, 1.0, 1.0));
662        legend.setFrame(new LineBorder());
663        legend.setPosition(RectangleEdge.BOTTOM);
664        legend.setHorizontalAlignment(HorizontalAlignment.LEFT);
665        
666        legend.setWidth(chartwidth-20);// geht nicht
667        legend.setItemFont(font);
668                legend.setItemPaint(foregroundcolor);
669
670                //RectangleInsets labelPadding;
671                legend.setItemLabelPadding(new RectangleInsets(2,2,2,2));
672                legend.setBorder(0,0,0,0); 
673                legend.setLegendItemGraphicLocation(RectangleAnchor.TOP_LEFT);
674                legend.setLegendItemGraphicPadding(new RectangleInsets(8,10,0,0));
675                chart.addLegend(legend);
676                
677        }
678
679
680
681        private void setBorder(JFreeChart chart, Plot plot) {
682                chart.setBorderVisible(false);
683                chart.setBorderPaint(foregroundcolor);
684                plot.setOutlinePaint(foregroundcolor);
685        }
686
687
688
689        private void setBackground(JFreeChart chart, Plot plot) {
690                //Color bg = backgroundcolor==null?databackgroundcolor:backgroundcolor;
691
692                chart.setBackgroundPaint(backgroundcolor);
693                plot.setBackgroundPaint(databackgroundcolor);
694                chart.setBorderPaint(databackgroundcolor);
695                
696                
697        plot.setOutlineVisible(false);
698                
699                // Pie
700                if(plot instanceof PiePlot) {
701                        PiePlot pp=(PiePlot) plot;
702                        pp.setLabelOutlinePaint(backgroundcolor); 
703                pp.setLabelBackgroundPaint(backgroundcolor);
704                pp.setLabelShadowPaint(backgroundcolor);
705                pp.setShadowPaint(backgroundcolor);
706                }
707                // Bar
708                /*if(plot instanceof CategoryPlot) {
709                        CategoryPlot cp=(CategoryPlot) plot;
710                        
711                }*/
712        }
713
714
715
716        
717 
718        private Font getFont() {
719                return new Font(font,fontstyle,fontsize);
720        }
721
722        private void writeOut(JFreeChart jfc) throws PageException, IOException {
723                final ChartRenderingInfo info=new ChartRenderingInfo();
724        
725                // map name
726                chartIndex++;
727                if(chartIndex<0)chartIndex=0;
728                String mapName="chart_"+chartIndex;
729                setUrl(jfc);
730                
731                // write out to variable
732                if(!StringUtil.isEmpty(name)){
733                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
734                        copy(baos, jfc,info);
735                        pageContext.setVariable(name, baos.toByteArray());
736                        return;
737                }
738                
739                // write out as link
740                String id=Md5.getDigestAsString(JavaConverter.serialize(this));
741                Resource graph = pageContext.getConfig().getTempDirectory().getRealResource("graph");
742                Resource res = graph.getRealResource(id);
743                if(!res.exists()) {
744                        clean(graph);
745                        copy(res.getOutputStream(),jfc,info);
746                } else {
747                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
748                        copy(baos, jfc,info);                   
749                }
750                
751                String contextPath = pageContext.getHttpServletRequest().getContextPath();
752                contextPath = StringUtil.isEmpty(contextPath) ? "/" : contextPath+"/";
753                String src=contextPath+"lucee/graph.cfm?img="+id+"&type="+formatToString(format);
754                
755                if(!StringUtil.isEmpty(source)) {
756                        pageContext.setVariable(source, src);
757                        return;
758                }
759                try {
760                        if(showtooltip || !StringUtil.isEmpty(url)) {
761                                String map=ChartUtilities.getImageMap(mapName,info).trim();
762                                pageContext.write(map);
763                        }
764                        pageContext.write("<img border=\"0\" usemap=\"#"+mapName+"\" src=\""+src+"\">");
765                } 
766                catch (IOException e) {
767                        throw Caster.toPageException(e);
768                }               
769        }
770
771        private void copy(OutputStream os, JFreeChart jfc, ChartRenderingInfo info) throws ApplicationException, IOException, ExpressionException {
772                //OutputStream os = null;
773                try {
774                        //os = res.getOutputStream();
775                        
776                        BufferedImage bi;
777                        if (format==FORMAT_JPG) {
778                                bi = jfc.createBufferedImage(chartwidth,chartheight,BufferedImage.TYPE_INT_RGB,info);
779                        } else {
780                                bi = jfc.createBufferedImage(chartwidth,chartheight,info);
781                        }
782                        Image img;
783                        
784                        // add border
785                        if(showborder) {
786                                try {
787                                        img = new Image(bi);
788                                        img.addBorder(1,Color.BLACK,Image.BORDER_TYPE_CONSTANT);
789                                        bi=img.getBufferedImage();
790                                }
791                                catch (PageException e) {}
792                        }
793                        if(format==FORMAT_PNG)          ChartUtilities.writeBufferedImageAsPNG(os, bi);
794                        else if(format==FORMAT_JPG)     ChartUtilities.writeBufferedImageAsJPEG(os, bi);
795                        else if(format==FORMAT_GIF)     {
796                                img = new lucee.runtime.img.Image(bi);
797                                img.writeOut(os, "gif",1,true);
798                                
799                                //throw new ApplicationException("format gif not supported");
800                        }
801                        else if(format==FORMAT_FLASH)throw new ApplicationException("format flash not supported");
802                }
803                finally {
804                        IOUtil.flushEL(os);
805                        IOUtil.closeEL(os);
806                }
807        }
808
809        private String formatToString(int format) {
810                if(format==FORMAT_GIF) return "gif";
811                if(format==FORMAT_JPG) return "jpeg";
812                if(format==FORMAT_PNG) return "png";
813                return "swf";
814        }
815
816        private void clean(Resource graph) throws IOException {
817                if(!graph.exists())graph.createDirectory(true);
818                else if(graph.isDirectory() && ResourceUtil.getRealSize(graph)>(1024*1024)) {
819                        
820                        Resource[] children = graph.listResources();
821                        long maxAge=System.currentTimeMillis()-(1000*60);
822                        for(int i=0;i<children.length;i++) {
823                                if(children[i].lastModified()<maxAge)
824                                        children[i].delete();
825                        }
826                }
827        }
828
829        private void chartBar() throws PageException, IOException {
830                // create the chart...
831        final JFreeChart chart = show3d?
832                ChartFactory.createBarChart3D(title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.VERTICAL,false,true,false):
833                ChartFactory.createBarChart  (title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.VERTICAL,false,true,false);
834        Plot p = chart.getPlot();
835        Font _font = getFont();
836        // settings
837        
838        
839        setBackground(chart,p);
840                setBorder(chart,p);
841                set3d(p);
842                setFont(chart,_font);
843                setLabelFormat(chart);
844                setLegend(chart, p, _font);
845        setTooltip(chart);
846                setScale(chart);
847        setAxis(chart);
848        setColor(chart);
849        
850        writeOut(chart);
851        }
852        
853
854
855
856
857        private void chartLine() throws PageException, IOException {
858                // create the chart...
859        final JFreeChart chart = show3d?
860                ChartFactory.createLineChart3D(title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.VERTICAL,false,true,false):
861                ChartFactory.createLineChart(title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.VERTICAL,false,true,false);
862        Plot p = chart.getPlot();
863        Font _font = getFont();
864        
865        // settings
866        setMarker(chart,p);
867        setBackground(chart,p);
868                setBorder(chart,p);
869                set3d(p);
870                setFont(chart,_font);
871                setLabelFormat(chart);
872                setLegend(chart, p, _font);
873        setTooltip(chart);
874                setScale(chart);
875        setAxis(chart);
876        setColor(chart);
877        
878        writeOut(chart);
879        }
880        
881        private void chartArea() throws PageException, IOException {
882                // create the chart...
883        final JFreeChart chart = ChartFactory.createAreaChart(title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.VERTICAL,false,true,false);
884        Plot p = chart.getPlot();
885        Font _font = getFont();
886        
887        // settings
888        setMarker(chart,p);
889        setBackground(chart,p);
890                setBorder(chart,p);
891                set3d(p);
892                setFont(chart,_font);
893                setLabelFormat(chart);
894                setLegend(chart, p, _font);
895        setTooltip(chart);
896                setScale(chart);
897        setAxis(chart);
898        setColor(chart);
899        
900        writeOut(chart);
901        }
902        
903        private void chartTimeLine() throws PageException, IOException {
904                // create the chart...
905        final JFreeChart chart = ChartFactory.createTimeSeriesChart(title,xaxistitle,yaxistitle,createTimeSeriesCollection(),false,true,false);
906        Plot p = chart.getPlot();
907        Font _font = getFont();
908        
909        // settings
910        setMarker(chart,p);
911        setBackground(chart,p);
912                setBorder(chart,p);
913                set3d(p);
914                setFont(chart,_font);
915                setLabelFormat(chart);
916                setLegend(chart, p, _font);
917        setTooltip(chart);
918                setScale(chart);
919        setAxis(chart);
920        setColor(chart);
921        
922        writeOut(chart);
923        }
924
925        private void chartHorizontalBar() throws PageException, IOException {
926                // create the chart...
927        final JFreeChart chart = show3d?
928                ChartFactory.createBarChart3D(title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.HORIZONTAL,false,true,false):
929                ChartFactory.createBarChart  (title,xaxistitle,yaxistitle,createDatasetCategory(),PlotOrientation.HORIZONTAL,false,true,false);
930        final CategoryPlot p = chart.getCategoryPlot();
931        p.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
932        Font _font = getFont();
933        // settings            
934        
935        setBackground(chart,p);
936                setBorder(chart,p);
937                set3d(p);
938                setFont(chart,_font);
939                setLabelFormat(chart);
940                setLegend(chart, p, _font);
941        setTooltip(chart);
942                setScale(chart);
943        setAxis(chart);
944        setColor(chart);
945        
946        writeOut(chart);
947        }
948        
949        private void chartScatter() throws PageException, IOException {
950                // create the chart...
951                final JFreeChart chart = ChartFactory.createScatterPlot(title,xaxistitle,yaxistitle,createXYSeriesCollection(),PlotOrientation.VERTICAL,false,true,false);
952                final XYPlot p = chart.getXYPlot();
953                Font _font = getFont();
954                // settings            
955
956                setBackground(chart,p);
957                setBorder(chart,p);
958                set3d(p);
959                setFont(chart,_font);
960                setLabelFormat(chart);
961                setLegend(chart, p, _font);
962                setTooltip(chart);
963                setScale(chart);
964                setAxis(chart);
965                setColor(chart);
966                
967                writeOut(chart);
968        }
969        
970        private void chartStep() throws PageException, IOException {
971                // create the chart...
972                final JFreeChart chart = ChartFactory.createXYStepChart(title,xaxistitle,yaxistitle,createXYSeriesCollection(),PlotOrientation.VERTICAL,false,true,false);
973                final XYPlot p = chart.getXYPlot();
974                Font _font = getFont();
975                // settings            
976                
977                setBackground(chart,p);
978                setBorder(chart,p);
979                set3d(p);
980                setFont(chart,_font);
981                setLabelFormat(chart);
982                p.getDomainAxis().setRange(Range.expandToInclude(p.getDomainAxis().getRange(), p.getDomainAxis().getUpperBound()+0.25));
983                p.getDomainAxis().setRange(Range.expandToInclude(p.getDomainAxis().getRange(), p.getDomainAxis().getLowerBound()-0.25));
984                setLegend(chart, p, _font);
985                setTooltip(chart);
986                setScale(chart);
987                setAxis(chart);
988                setColor(chart);
989                
990                writeOut(chart);
991        }
992        
993
994
995        private void setMarker(JFreeChart chart, Plot p) {
996                if(!showmarkers) return;
997                
998                if(markersize<1 || markersize>100) markersize=4;
999                
1000                
1001                
1002                if(p instanceof XYPlot) {
1003                        XYPlot xyp=(XYPlot) p;
1004                        XYItemRenderer r = xyp.getRenderer();
1005                        if (r instanceof XYLineAndShapeRenderer) {
1006                                XYLineAndShapeRenderer xyr = (XYLineAndShapeRenderer) r;
1007                                xyr.setBaseShapesVisible(true);
1008                                xyr.setBaseShapesFilled(true);
1009                                
1010                                int seriesCount=_series.size();
1011                                for(int i=0;i<seriesCount;i++){
1012                                        xyr.setSeriesShapesVisible(i, true);
1013                                        xyr.setSeriesItemLabelsVisible(i, true);
1014                                        xyr.setSeriesShape(i, ShapeUtilities.createDiamond(markersize));
1015                                        xyr.setUseFillPaint(true);
1016                                        xyr.setBaseFillPaint(databackgroundcolor);
1017                                }
1018                        }
1019                }
1020                else if(p instanceof CategoryPlot) {
1021                        CategoryPlot cp=(CategoryPlot) p;
1022                        CategoryItemRenderer r = cp.getRenderer();
1023                        if (r instanceof LineAndShapeRenderer) {
1024                                LineAndShapeRenderer lsr = (LineAndShapeRenderer)r;
1025                        
1026                                int seriesCount=_series.size();
1027                                for(int i=0;i<seriesCount;i++){
1028                                        lsr.setSeriesShapesVisible(i, true);
1029                                        lsr.setSeriesItemLabelsVisible(i, true);
1030                                        lsr.setSeriesShape(i, ShapeUtilities.createDiamond(markersize));
1031                                lsr.setUseFillPaint(true);
1032                                lsr.setBaseFillPaint(databackgroundcolor);
1033                                }
1034                        }
1035                }
1036        }
1037
1038
1039
1040        private void setAxis(JFreeChart chart) {
1041                Plot plot = chart.getPlot();
1042                if(plot instanceof CategoryPlot) {
1043                        CategoryPlot cp=(CategoryPlot)plot;
1044                        
1045                        // Y
1046                        cp.setDomainGridlinesVisible(showygridlines);
1047                        if(showygridlines) cp.setDomainGridlinePaint(foregroundcolor);
1048                        
1049                        cp.setRangeGridlinesVisible(showxgridlines!=NO);
1050                        if(showxgridlines==NONE)cp.setRangeGridlinePaint(Color.GRAY);
1051                        else if(showxgridlines==YES)cp.setRangeGridlinePaint(foregroundcolor);
1052                }
1053                else if(plot instanceof XYPlot) {
1054                        XYPlot cp=(XYPlot)plot;
1055                        
1056                        // Y
1057                        cp.setDomainGridlinesVisible(showygridlines);
1058                        if(showygridlines) cp.setDomainGridlinePaint(foregroundcolor);
1059                        
1060                        cp.setRangeGridlinesVisible(showxgridlines!=NO);
1061                        if(showxgridlines==NONE)cp.setRangeGridlinePaint(Color.GRAY);
1062                        else if(showxgridlines==YES)cp.setRangeGridlinePaint(foregroundcolor);
1063                }
1064        }
1065
1066
1067
1068        private void setTooltip(JFreeChart chart) {
1069                Plot plot = chart.getPlot();
1070                if(plot instanceof PiePlot) {
1071                        PiePlot pp = (PiePlot)plot;             
1072                        
1073                        pp.setToolTipGenerator(new PieToolTipGeneratorImpl(labelFormat));
1074                        
1075                }
1076                else if(plot instanceof CategoryPlot) {
1077                        CategoryPlot cp=(CategoryPlot) plot;
1078                        CategoryItemRenderer renderer = cp.getRenderer();
1079                        renderer.setBaseToolTipGenerator(new CategoryToolTipGeneratorImpl(labelFormat));
1080                }
1081                /*else if(plot instanceof XYPlot) {
1082                        XYPlot cp=(XYPlot) plot;
1083                        XYItemRenderer renderer = cp.getRenderer();
1084                        renderer.setBaseToolTipGenerator(new XYToolTipGeneratorImpl(labelFormat));
1085                }*/
1086                
1087        }
1088
1089        private void setUrl(JFreeChart chart) {
1090                if(StringUtil.isEmpty(url)) return;
1091                Plot plot = chart.getPlot();
1092                if(plot instanceof PiePlot) {
1093                        PiePlot pp = (PiePlot)plot;             
1094                        pp.setURLGenerator(new PieURLGenerator() {
1095                            public String generateURL(PieDataset dataset, Comparable key, int pieIndex) {
1096                                if(!StringUtil.contains(url, "?")) url += "?series=$SERIESLABEL$&category=$ITEMLABEL$&value=$VALUE$";
1097                                String retUrl=StringUtil.replace(url, "$ITEMLABEL$", URLUtilities.encode(key.toString(),"UTF-8"),false,true);
1098                                retUrl = StringUtil.replace(retUrl,"$SERIESLABEL$",Integer.toString(pieIndex),false,true);
1099                                retUrl = StringUtil.replace(retUrl,"$VALUE$",URLUtilities.encode(dataset.getValue(key).toString(),"UTF-8"),false,true);
1100                                return retUrl;
1101                            }
1102                        });
1103                }
1104                else if(plot instanceof CategoryPlot) {
1105                        CategoryPlot cp=(CategoryPlot) plot;
1106                        CategoryItemRenderer renderer = cp.getRenderer();
1107                        renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator() {
1108                            public String generateURL(CategoryDataset dataset, int series,int category) {
1109                                if(!StringUtil.contains(url, "?")) url += "?series=$SERIESLABEL$&category=$ITEMLABEL$&value=$VALUE$";
1110                                String retUrl=StringUtil.replace(url, "$ITEMLABEL$", URLUtilities.encode(dataset.getColumnKey(category).toString(),"UTF-8"),false,true);
1111                                retUrl = StringUtil.replace(retUrl,"$SERIESLABEL$",URLUtilities.encode(dataset.getRowKey(series).toString(),"UTF-8"),false,true);
1112                                retUrl = StringUtil.replace(retUrl,"$VALUE$",URLUtilities.encode(dataset.getValue(series, category).toString(),"UTF-8"),false,true);
1113                                return retUrl;
1114                            }
1115                        });
1116                }
1117                else if(plot instanceof XYPlot) {
1118                        XYPlot cp=(XYPlot) plot;
1119                        XYItemRenderer renderer = cp.getRenderer();
1120                        renderer.setURLGenerator(new StandardXYURLGenerator() {
1121                            public String generateURL(XYDataset dataset, int series,int category) {
1122                                if(!StringUtil.contains(url, "?")) url += "?series=$SERIESLABEL$&category=$ITEMLABEL$&value=$VALUE$";
1123                                String itemLabel = _plotItemLables.get(category+1) != null ? _plotItemLables.get(category+1) : dataset.getX(series, category).toString();
1124                                String retUrl=StringUtil.replace(url, "$ITEMLABEL$", URLUtilities.encode(itemLabel,"UTF-8"),false,true);
1125                                retUrl = StringUtil.replace(retUrl,"$SERIESLABEL$",URLUtilities.encode(dataset.getSeriesKey(series).toString(),"UTF-8"),false,true);
1126                                retUrl = StringUtil.replace(retUrl,"$VALUE$",URLUtilities.encode(dataset.getY(series, category).toString(),"UTF-8"),false,true);
1127                                return retUrl;
1128                            }
1129                        });
1130                }
1131                
1132        }
1133        
1134
1135
1136        private void setScale(JFreeChart chart) {
1137                Plot plot = chart.getPlot();
1138                if(plot instanceof CategoryPlot) {
1139                        CategoryPlot cp=(CategoryPlot) plot;
1140                        ValueAxis rangeAxis = cp.getRangeAxis();
1141                        Range r=rangeAxis.getRange();
1142                        double lower=r.getLowerBound();
1143                        double upper=r.getUpperBound();
1144                        
1145                        if(labelFormat==LabelFormatUtil.LABEL_FORMAT_DATE && rangeAxis.getRange().getLowerBound()==0) {
1146                                lower = smallest;
1147                                upper=biggest;
1148                                try     {
1149                                        DateTime d = Caster.toDate(Caster.toDouble(lower),true,null,null);
1150                                        lower = DateAdd.call(pageContext,"yyyy", -1, d).castToDoubleValue(lower);       
1151                                }
1152                                catch (PageException e) {}
1153                        }
1154                        if(!Double.isNaN(scalefrom))lower=scalefrom;
1155                        if(!Double.isNaN(scaleto))upper=scaleto;
1156                        rangeAxis.setRange(new Range(lower,upper),true,true);
1157                }
1158                else if(plot instanceof XYPlot) {
1159                        XYPlot cp=(XYPlot) plot;
1160                        ValueAxis rangeAxis = cp.getRangeAxis();
1161                        Range r=rangeAxis.getRange();
1162                        double lower=r.getLowerBound();
1163                        double upper=r.getUpperBound();
1164                        
1165                        if(labelFormat==LabelFormatUtil.LABEL_FORMAT_DATE && rangeAxis.getRange().getLowerBound()==0) {
1166                                lower = smallest;
1167                                upper=biggest;
1168                                try     {
1169                                        DateTime d = Caster.toDate(Caster.toDouble(lower),true,null,null);
1170                                        lower = DateAdd.call(pageContext,"yyyy", -1, d).castToDoubleValue(lower);       
1171                                }
1172                                catch (PageException e) {}
1173                        }
1174                        if(!Double.isNaN(scalefrom))lower=scalefrom;
1175                        if(!Double.isNaN(scaleto))upper=scaleto;
1176                        rangeAxis.setRange(new Range(lower,upper),true,true);
1177                }
1178        }
1179
1180        private void setLabelFormat(JFreeChart chart) {
1181                Plot plot = chart.getPlot();
1182                if(plot instanceof CategoryPlot) {
1183                        CategoryPlot cp=(CategoryPlot) plot;
1184                        ValueAxis rangeAxis = cp.getRangeAxis();
1185                        rangeAxis.setAutoTickUnitSelection(true);
1186                        rangeAxis.setStandardTickUnits(new TickUnitsImpl(rangeAxis.getStandardTickUnits(),labelFormat));
1187                        CategoryItemRenderer r = cp.getRenderer();
1188                        r.setBaseItemLabelsVisible(false);
1189                        
1190                        CategoryAxis da = cp.getDomainAxis();
1191                        if(!showXLabel)da.setTickLabelsVisible(false);
1192                        da.setCategoryLabelPositions(labelPosition);
1193                        da.setMaximumCategoryLabelWidthRatio(100);
1194                        //da.setVisible(false);
1195                }
1196                if(plot instanceof XYPlot) {
1197                        XYPlot cp=(XYPlot) plot;
1198                        ValueAxis rangeAxis = cp.getRangeAxis();
1199                        rangeAxis.setAutoTickUnitSelection(true);
1200                        rangeAxis.setStandardTickUnits(new TickUnitsImpl(rangeAxis.getStandardTickUnits(),labelFormat));
1201                        XYItemRenderer r = cp.getRenderer();
1202                        r.setBaseItemLabelsVisible(false);
1203                        ValueAxis da = cp.getDomainAxis();
1204                        if(!_plotItemLables.isEmpty()){
1205                                _plotItemLables.add(0, "");
1206                                String[] cols = _plotItemLables.toArray(new String[_plotItemLables.size()]);
1207                                SymbolAxis sa = new SymbolAxis(da.getLabel(), cols);
1208                                sa.setRange(da.getRange());
1209                                if(labelPosition == LABEL_VERTICAL) {
1210                                        sa.setVerticalTickLabels(true);
1211                                }
1212                                cp.setDomainAxis(sa);
1213                        }
1214                        if(!showXLabel)cp.getDomainAxis().setTickLabelsVisible(false);
1215                        //da.setVisible(false);
1216                }
1217        }
1218
1219
1220
1221        // set individual colors for series
1222        private void setColor(JFreeChart chart) {
1223                Plot p = chart.getPlot();
1224                if(p instanceof CategoryPlot) {
1225                        CategoryPlot cp=(CategoryPlot) p;
1226                        
1227                        CategoryItemRenderer renderer = cp.getRenderer();
1228                
1229                        
1230                        
1231                        Iterator<ChartSeriesBean> cs = _series.iterator();
1232                        //int seriesCount=_series.size();
1233                        ChartSeriesBean csb;
1234                        GradientPaint gp;
1235                        Color c=null;
1236                        Color[] ac;
1237                        
1238                        int index=0;
1239                        while(cs.hasNext()) {
1240                                csb= cs.next();
1241                                // more than 1 series
1242                                //if(seriesCount>1) {
1243                                        c=csb.getSeriesColor();
1244                                        if(c==null) {
1245                                                ac=csb.getColorlist();
1246                                                if(ac!=null && ac.length>0)c=ac[0];
1247                                        }
1248                                        
1249                                //}
1250                                if(c==null) continue;
1251                                gp = new GradientPaint(0.0f, 0.0f, c, 0.0f, 0.0f,c);
1252                                renderer.setSeriesPaint(index++, gp);
1253                        }
1254                }
1255                else if(p instanceof XYPlot) {
1256                        XYPlot cp=(XYPlot) p;
1257                        
1258                        XYItemRenderer renderer = cp.getRenderer();
1259                
1260                        
1261                        
1262                        Iterator<ChartSeriesBean> cs = _series.iterator();
1263                        //int seriesCount=_series.size();
1264                        ChartSeriesBean csb;
1265                        GradientPaint gp;
1266                        Color c=null;
1267                        Color[] ac;
1268                        
1269                        int index=0;
1270                        while(cs.hasNext()) {
1271                                csb= cs.next();
1272                                // more than 1 series
1273                                //if(seriesCount>1) {
1274                                        c=csb.getSeriesColor();
1275                                        if(c==null) {
1276                                                ac=csb.getColorlist();
1277                                                if(ac!=null && ac.length>0)c=ac[0];
1278                                        }
1279                                        
1280                                //}
1281                                if(c==null) continue;
1282                                gp = new GradientPaint(0.0f, 0.0f, c, 0.0f, 0.0f,c);
1283                                renderer.setSeriesPaint(index++, gp);
1284                        }
1285                }
1286        }
1287
1288
1289
1290        private DefaultPieDataset createDatasetPie() {
1291                DefaultPieDataset dataset = new DefaultPieDataset();
1292                ChartSeriesBean csb =  _series.get(0);
1293        
1294                ChartDataBean cdb;
1295        // write data set
1296        Iterator itt = csb.getDatas().iterator();
1297        while(itt.hasNext()) {
1298                cdb=(ChartDataBean) itt.next();
1299                dataset.setValue(cdb.getItemAsString(), cdb.getValue());
1300        }       
1301        return dataset;
1302    }
1303        
1304
1305        
1306        
1307
1308        private CategoryDataset createDatasetCategory() {
1309        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
1310        Iterator<ChartSeriesBean> it = _series.iterator();
1311        //int seriesCount=_series.size();
1312        Iterator itt;
1313        List datas;
1314        ChartSeriesBean csb;
1315        ChartDataBean cdb;
1316        int count=0;
1317        smallest=Double.MAX_VALUE;
1318        biggest = Double.MIN_VALUE;
1319        String label;
1320        boolean hasLabels=false;
1321        while(it.hasNext()) {
1322                count++;
1323                csb= it.next();
1324                label=csb.getSeriesLabel();
1325                if(StringUtil.isEmpty(label))label=""+count;
1326                else hasLabels=true;
1327                datas = csb.getDatas();
1328                if(sortxaxis)Collections.sort(datas);
1329            itt=datas.iterator();
1330            while(itt.hasNext()) {
1331                        cdb=(ChartDataBean) itt.next();
1332                        if(smallest>cdb.getValue())smallest=cdb.getValue();
1333                        if(biggest<cdb.getValue())biggest=cdb.getValue();
1334                        //if(seriesCount>1)
1335                        
1336                        dataset.addValue(cdb.getValue(), label,cdb.getItemAsString());
1337                        
1338                        //else dataset.addValue(cdb.getValue(), cdb.getItem(),"");
1339                        
1340                
1341                }
1342        }
1343        if(!hasLabels)showlegend=false;
1344        return dataset;
1345    }
1346        private XYDataset createTimeSeriesCollection() {
1347                TimeZone tz = ThreadLocalPageContext.getTimeZone();
1348                final TimeSeriesCollection coll=new TimeSeriesCollection(tz);
1349                
1350        //final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
1351        Iterator<ChartSeriesBean> it = _series.iterator();
1352        //int seriesCount=_series.size();
1353        Iterator itt;
1354        List datas;
1355        ChartSeriesBean csb;
1356        ChartDataBean cdb;
1357        int count=0;
1358        smallest=Double.MAX_VALUE;
1359        biggest = Double.MIN_VALUE;
1360        String label;
1361        boolean hasLabels=false;
1362        while(it.hasNext()) {
1363                count++;
1364                csb=it.next();
1365                label=csb.getSeriesLabel();
1366                if(StringUtil.isEmpty(label))label=""+count;
1367                else hasLabels=true;
1368                datas = csb.getDatas();
1369                if(sortxaxis)Collections.sort(datas);
1370            itt=datas.iterator();
1371            TimeSeries ts=new TimeSeries(label,Second.class);
1372            while(itt.hasNext()) {
1373                        cdb=(ChartDataBean) itt.next();
1374                        if(smallest>cdb.getValue())smallest=cdb.getValue();
1375                        if(biggest<cdb.getValue())biggest=cdb.getValue();
1376                        //if(seriesCount>1)
1377                        ts.addOrUpdate(new Second(DateCaster.toDateSimple(cdb.getItem(),DateCaster.CONVERTING_TYPE_NONE,false, tz,null)), cdb.getValue());
1378                        
1379                        //else dataset.addValue(cdb.getValue(), cdb.getItem(),"");
1380                        
1381                
1382                }
1383            coll.addSeries(ts);
1384        }
1385        if(!hasLabels)showlegend=false;
1386        return coll;
1387    }
1388        private XYDataset createXYSeriesCollection() {
1389                final XYSeriesCollection coll=new XYSeriesCollection();
1390                Iterator<ChartSeriesBean> it = _series.iterator();
1391                Iterator itt;
1392                List datas;
1393                ChartSeriesBean csb;
1394                ChartDataBean cdb;
1395                int count=0;
1396                String label;
1397                boolean hasLabels=false;
1398                while(it.hasNext()) {
1399                        count++;
1400                        csb=it.next();
1401                        label=csb.getSeriesLabel();
1402                        if(StringUtil.isEmpty(label))label=""+count;
1403                        else hasLabels=true;
1404                        datas = csb.getDatas();
1405                        if(sortxaxis)Collections.sort(datas);
1406                        itt=datas.iterator();
1407                        XYSeries xySeries=new XYSeries(label,false,true);
1408                        int stepNum = 0;
1409                        while(itt.hasNext()) {
1410                                cdb=(ChartDataBean) itt.next();
1411//                              if(cdb.getItem().toString().matches("-?\\d+(\\.\\d+)?")){
1412//                                      xySeries.add(Double.parseDouble(cdb.getItem().toString()),cdb.getValue());
1413//                              } else {
1414                                        stepNum++;
1415                                        xySeries.add(stepNum,cdb.getValue());
1416//                              }
1417                                if(!_plotItemLables.contains(cdb.getItem().toString()))_plotItemLables.add(cdb.getItem().toString());
1418                        }
1419                        coll.addSeries(xySeries);
1420                }
1421                if(!hasLabels)showlegend=false;
1422                return coll;
1423        }
1424        
1425        /**
1426         * @param url the url to set
1427         */
1428        public void setUrl(String url) {
1429                this.url = url;
1430        }
1431
1432        /**
1433         * @param xoffset the xoffset to set
1434         */
1435        public void setXoffset(double xoffset) {
1436                this.xoffset = xoffset;
1437        }
1438
1439        /**
1440         * @param yoffset the yoffset to set
1441         */
1442        public void setYoffset(double yoffset) {
1443                this.yoffset = yoffset;
1444        }
1445
1446        /**
1447         * @param yaxistype the yaxistype to set
1448         */
1449        public void setYaxistype(String yaxistype) {
1450                this.yaxistype = yaxistype;
1451        }
1452        /**
1453         * @param yaxistype the yaxistype to set
1454         */
1455        public void setXaxistype(String xaxistype) {
1456                this.xaxistype = xaxistype;
1457        }
1458        
1459}