package hep.aida.ref.plotter.adapter;

import jas.hist.CustomOverlay;
import jas.hist.DataSource;
import jas.hist.JASHist1DHistogramStyle;
import jas.hist.JASHistData;
import jas.hist.JASHistStyle;
import jas.hist.XYDataSource;
import jas.plot.CoordinateTransformation;
import jas.plot.DateCoordinateTransformation;
import jas.plot.DoubleCoordinateTransformation;
import jas.plot.MutableLegendEntry;
import jas.plot.OverlayContainer;
import jas.plot.PlotGraphics;

import java.awt.BasicStroke;

/**
 * Overlay that can be used with XYDataSource to represent time histories
 * It draws straight horizontal line after the point and vertical just before 
 * the next point:
 *
 *        *----- 
 *   *----|
 */

public class TimeHistoryOverlay implements CanSetData, CustomOverlay, MutableLegendEntry
{
   private XYDataSource source;
   private OverlayContainer container;
   private JASHistData data;
   private JASHist1DHistogramStyle style;
   private String[] labels;
   private double[] xPoly;
   private double[] yPoly;
   private double xmax;
   private double xmin;
   private int oldn = 0;

   private static final float[][] lineStyles = {null, { 1, 5 },{ 4, 6 },{ 6, 4, 2, 4 }};
   
   public TimeHistoryOverlay()
   {
   }


   public void setData(JASHistData data) {
       this.data = data;
   }

   public void setStyle(JASHistStyle s) {
       this.style = (JASHist1DHistogramStyle) s;
       if (style != null) style.setShowHistogramBars(true);
   }

   public JASHist1DHistogramStyle getStyle() {
       return style;
   }


    // LegendEntry methods

   public String getTitle()
   {
      return source.getTitle();
   }

   public void paintIcon(PlotGraphics g, int width, int height)
   {
      if (style == null) style = (JASHist1DHistogramStyle) data.getStyle();
      if (style.getShowDataPoints())
      {
         g.setColor(style.getDataPointColor());
         g.drawSymbol( width / 2, height / 2, width / 2, style.getDataPointStyle());
      }
      else if (style.getShowHistogramBars())
      {
         if ( style.getHistogramFill() ) {
            g.setColor(style.getHistogramBarColor());
            g.fillRect(1, 1, width - 2, height - 2);
         }
         else {
            g.setColor(style.getHistogramBarLineColor());
            BasicStroke s = new BasicStroke(style.getHistogramBarLineWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getHistogramBarLineStyle()],0);
            g.setStroke(s);
            g.drawLine(1, height/2, width-2, height/2);
            g.setStroke(null);
         }
      }
      else if (style.getShowLinesBetweenPoints())
      {
         g.setColor(style.getLineColor());
         BasicStroke s = new BasicStroke(style.getLinesBetweenPointsWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0);
         g.setStroke(s);
         g.drawLine(1, height/2, width-2, height/2);
         g.setStroke(null);
      }
      else if (style.getShowErrorBars())
      {
         g.setColor(style.getErrorBarColor());
         BasicStroke s = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getErrorBarStyle()],0);
         g.setStroke(s);
         g.drawLine(1, height/2, width-2, height/2);
         g.setStroke(null);
      }
      else if (style.getHistogramFill())
      {
         g.setColor(style.getHistogramBarColor());
         g.fillRect(1, 1, width - 2, height - 2);
      }
   }


    // MutableLegendEntry methods 

   public void setTitle(String newTitle)
   {
   }

   public boolean titleIsChanged()
   {
       return false; //source.isLegendChanged();
   }



    // CustomOverlay mathods

   public void setDataSource(DataSource sr) {
       if (sr instanceof XYDataSource) this.source = (XYDataSource) sr;
       else throw new IllegalArgumentException("DataSource is not XYDataSource,  DataSource="+sr.toString());
   }


    // Overlay methods

   public void containerNotify(OverlayContainer c)
   {
      this.container = c;
   }

   public void paint(PlotGraphics g, boolean isPrinting)
   {
      if (style == null) style = (JASHist1DHistogramStyle) data.getStyle();

      CoordinateTransformation xp = container.getXTransformation();
      final CoordinateTransformation yp = container.getYTransformation(data.getYAxis());

      if (xp instanceof DateCoordinateTransformation)
      {
         xp = new DateTransformationConverter((DateCoordinateTransformation) xp);
      }

      if (xp instanceof DoubleCoordinateTransformation && yp instanceof DoubleCoordinateTransformation)
      {
         final DoubleCoordinateTransformation xt = (DoubleCoordinateTransformation) xp;
         final DoubleCoordinateTransformation yt = (DoubleCoordinateTransformation) yp;

	 xmin = xt.getPlotMin();
	 xmax = xt.getPlotMax();

         final int bins = source.getNPoints();
         final double binWidth = (xmax - xmin) / bins;
         final double pixelWidth = (xt.convert(xmax) - xt.convert(xmin)) / bins;
         final boolean outline = pixelWidth > 5;
         final double errorBarWidth = Math.min(binWidth, (3 * binWidth) / pixelWidth);

         g.setTransformation(xt, yt);

         double x = xmin;
         double oldx = xmin;

         // y0 is used as the base of histogram bars. It should
         // be 0 unless there is a suppressed 0 on the Y axis.
         double y0 = 0;
         if (yt.getPlotMin() > y0)
         {
            y0 = yt.getPlotMin();
         }
         if (yt.getPlotMax() < y0)
         {
            y0 = yt.getPlotMax();
         }

         if ((style.getShowLinesBetweenPoints() || style.getShowDataPoints()) && bins != oldn) {
	     xPoly = new double[bins+1];
	     yPoly = new double[bins+1];
	     oldn = bins;
	 }
         int index = 0;
	 double y = source.getY(index);
	 x = source.getX(index);

         double oldy = y;

	 xPoly[index] = x;
	 yPoly[index] = y;


         for (int i = 0; i < bins; i++)
         {
            y = source.getY(i);
            x = source.getX(i);

	    //System.out.println("N="+i+"\ty="+y+"\tx="+x);

	    // skip point if X or Y == Double.NaN
	    if (Double.isNaN(y) || Double.isNaN(x)) continue;

	    xPoly[index] = x;
	    yPoly[index] = y;

            BasicStroke s = new BasicStroke(style.getHistogramBarLineWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getHistogramBarLineStyle()],0);
            g.setStroke(s);
	    if (style.getShowHistogramBars()) {
		g.setColor(style.getHistogramBarColor());
		if (style.getHistogramFill()) {
		    g.setColor(style.getHistogramBarLineColor());
		    if (i > 0) g.fillRect(oldx, y0, x, oldy);
		    if (outline) {
                        g.drawRect(oldx, y0, x, oldy);
		    } else {
                        if (i > 0) g.drawLine(oldx, oldy, x, oldy);
                        g.drawLine(x, oldy, x, y);
		    }
		} else {
		    g.setColor(style.getHistogramBarLineColor());
		    g.drawLine(oldx, oldy, x, oldy);
		    g.drawLine(x, oldy, x, y);
		}
            }

            if (style.getShowErrorBars())
            {
		g.setColor(style.getErrorBarColor());
		s = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getErrorBarStyle()],0);
		g.setStroke(s);

		//final double xm = (binWidth == 0) ? x : (oldx + (binWidth / 2));
		final double xm = x;
		final double xe = errorBarWidth;
		final double yplus = y + source.getPlusError(i);
		final double yminus = y - source.getMinusError(i);
		if (!Double.isNaN(yplus) && !Double.isNaN(yminus) && yminus != yplus) {
		    //System.out.println("***** xm="+xm+",  xe="+xe+",  y="+y+", yminus="+yminus+", yplus="+yplus);
		    g.drawLine(xm, yplus, xm, yminus);
		    if (outline)
			{
			    BasicStroke ss = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10);
			    g.setStroke(ss);
			    g.drawLine(xm - xe, yplus, xm + xe, yplus);
			    g.drawLine(xm - xe, yminus, xm + xe, yminus);
			}
		}
            }
         
            oldx = x;
            oldy = y;
	    index++;

	 } // end for

	 if (index > 0) {
	     if (style.getShowLinesBetweenPoints()) {
		 g.setColor(style.getLineColor());
		 BasicStroke s = new BasicStroke(style.getLinesBetweenPointsWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0);
		 g.setStroke(s);
		 g.drawPolyLine(xPoly, yPoly, index);
	     }
	     if (style.getShowDataPoints()) {
		 g.setColor(style.getDataPointColor());
		 g.drawPolySymbol(xPoly, yPoly, style.getDataPointSize(), style.getDataPointStyle(), index);
	     }
	 }

	 // Draw line from the last point till the end of the plot
	 x = xmax;  
	 if (x > oldx) {
	     if (style.getShowHistogramBars()) {
		 BasicStroke s = new BasicStroke(style.getHistogramBarLineWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getHistogramBarLineStyle()],0);
		 g.setStroke(s);
		 g.setColor(style.getHistogramBarColor());
		 if (style.getHistogramFill()) {
		     g.setColor(style.getHistogramBarLineColor());
		     g.fillRect(oldx, y0, x, oldy);
		     if (outline) {
			 g.drawRect(oldx, y0, x, oldy);
		     } else {
			 g.drawLine(oldx, oldy, x, oldy);
			 //g.drawLine(x, oldy, x, y);
		     }
		 } else {
		     g.setColor(style.getHistogramBarLineColor());
		     g.drawLine(oldx, oldy, x, oldy);
		 }
	    }
	 } // end drawing last point
      }
   }

    private class DateTransformationConverter implements DoubleCoordinateTransformation
    {
	private DateCoordinateTransformation dateCT;
	
	DateTransformationConverter(DateCoordinateTransformation dateCT)
	{
	    this.dateCT = dateCT;
	}	
	public double convert(double d)
	{
	    return dateCT.convert((long) (d*1000));
	}
	public double unConvert(double i)
	{
	    return dateCT.map(i)/1000.;
	}
	public double getPlotMin()
	{
	    return dateCT.getAxisMin()/1000.;
	}
	public double getPlotMax()
	{
	    return dateCT.getAxisMax()/1000.;
	}
    }
}

 

Ads help maintain this website.