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