Package org.pentaho.reporting.libraries.libsparklines

Source Code of org.pentaho.reporting.libraries.libsparklines.BarGraphDrawable

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2008 - 2009 Larry Ogrodnek, Pentaho Corporation and Contributors.  All rights reserved.
*/

package org.pentaho.reporting.libraries.libsparklines;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;

import org.pentaho.reporting.libraries.libsparklines.util.GraphUtils;

/**
* A very fast and very simple bar-graph drawable. This code is based on the BarGraph class writen by Larry Ogrodnek
* but instead of producing a low-resolution image, this class writes the content into a Graphics2D context.
*
* @author Thomas Morgner
*/
public class BarGraphDrawable
{
  private static final int DEFAULT_SPACING = 2;

  private static final Color DEFAULT_COLOR = Color.gray;
  private static final Color DEFAULT_HIGH_COLOR = Color.black;
  private static final Color DEFAULT_LAST_COLOR = Color.red;
  private static final Number[] EMPTY = new Number[0];

  private Number[] data;
  private Color color;
  private Color highColor;
  private Color lastColor;
  private Color background;
  private int spacing;

  /**
   * Creates a default bargraph drawable with some sensible default colors and spacings.
   */
  public BarGraphDrawable()
  {
    this.highColor = BarGraphDrawable.DEFAULT_HIGH_COLOR;
    this.lastColor = BarGraphDrawable.DEFAULT_LAST_COLOR;
    this.color = BarGraphDrawable.DEFAULT_COLOR;
    this.spacing = BarGraphDrawable.DEFAULT_SPACING;
    this.data = EMPTY;
  }

  /**
   * Returns the numeric data for the drawable or null, if the drawable has no data.
   *
   * @return the data.
   */
  public Number[] getData()
  {
    return (Number[]) data.clone();
  }

  /**
   * Defines the numeric data for the drawable or null, if the drawable has no data.
   *
   * @param data the data (can be null).
   */
  public void setData(final Number[] data)
  {
    this.data = (Number[]) data.clone();
  }

  /**
   * Returns the main color for the bars.
   *
   * @return the main color for the bars, never null.
   */
  public Color getColor()
  {
    return color;
  }

  /**
   * Defines the main color for the bars.
   *
   * @param color the main color for the bars, never null.
   */
  public void setColor(final Color color)
  {
    if (color == null)
    {
      throw new NullPointerException();
    }
    this.color = color;
  }

  /**
   * Returns the color for the highest bars. This property is optional and the high-color can be null.
   *
   * @return the color for the highest bars, or null if high bars should not be marked specially.
   */
  public Color getHighColor()
  {
    return highColor;
  }

  /**
   * Defines the color for the highest bars. This property is optional and the high-color can be null.
   *
   * @param highColor the color for the highest bars, or null if high bars should not be marked specially.
   */
  public void setHighColor(final Color highColor)
  {
    this.highColor = highColor;
  }

  /**
   * Returns the color for the last bar. This property is optional and the last-bar-color can be null.
   *
   * @return the color for the last bar in the graph, or null if last bars should not be marked specially.
   */
  public Color getLastColor()
  {
    return lastColor;
  }

  /**
   * Defines the color for the last bar. This property is optional and the last-bar-color can be null.
   *
   * @param lastColor the color for the last bar in the graph, or null if last bars should not be marked specially.
   */
  public void setLastColor(final Color lastColor)
  {
    this.lastColor = lastColor;
  }

  /**
   * Returns the color for the background of the graph. This property can be null, in which case the bar
   * will have a transparent background.
   *
   * @return color for the background or null, if the graph has a transparent background color.
   */
  public Color getBackground()
  {
    return background;
  }

  /**
   * Defines the color for the background of the graph. This property can be null, in which case the bar
   * will have a transparent background.
   *
   * @param background the background or null, if the graph has a transparent background color.
   */
  public void setBackground(final Color background)
  {
    this.background = background;
  }

  /**
   * Returns the spacing between the bars.
   *
   * @return the spacing between the bars.
   */
  public int getSpacing()
  {
    return spacing;
  }

  /**
   * Defines the spacing between the bars.
   *
   * @param spacing the spacing between the bars.
   */
  public void setSpacing(final int spacing)
  {
    this.spacing = spacing;
  }

  /**
   * Draws the bar-graph into the given Graphics2D context in the given area. This method will not draw a graph
   * if the data given is null or empty.
   *
   * @param g2 the graphics context on which the bargraph should be rendered.
   * @param drawArea the area on which the bargraph should be drawn.
   */
  public void draw(Graphics2D g2, Rectangle2D drawArea)
  {
    if (g2 == null)
    {
      throw new NullPointerException();
    }
    if (drawArea == null)
    {
      throw new NullPointerException();
    }

    final int height = (int) drawArea.getHeight();
    if (height <= 0)
    {
      return;
    }

    final Graphics2D g = (Graphics2D) g2.create();
    g.translate(drawArea.getX(), drawArea.getY());
    if (background != null)
    {
      g.setBackground(background);
      g.clearRect(0, 0, (int) drawArea.getWidth(), height);
    }

    if (data == null || data.length == 0)
    {
      g.dispose();
      return;
    }

    final float scale = GraphUtils.getDivisor(data, height);
    final float axe = GraphUtils.getAxe(data) / scale;
    final float avg = computeAverage(data);

    final float spacing1 = getSpacing();
    final float barWidth = (float) ((drawArea.getWidth() - (spacing1 * data.length)) / (float) data.length);

    float x = 0;

    final double canvasHeight = drawArea.getHeight();
    final Rectangle2D.Double bar = new Rectangle2D.Double();
    for (int index = 0; index < data.length; index++)
    {
      final Number value = data[index];
      if (value == null)
      {
        x += (barWidth + spacing1);
        continue;
      }

      final float h = (int) (value.doubleValue() / scale);

      final float intVal = value.floatValue();
      if (index == (data.length - 1) && lastColor != null)
      {
        g.setPaint(lastColor);
      }
      else if (intVal < avg || (highColor == null))
      {
        g.setPaint(color);
      }
      else
      {
        g.setPaint(highColor);
      }

      if (axe == 0)
      {
        // only positive values, bottom aligned
        bar.setRect(x, (canvasHeight - h), barWidth, h);
      }
      else if(axe < 0)
      {
        // only negative values, top aligned
        bar.setRect(x, 0, barWidth, h < 0 ? -h : h);
      }
      else
      {
        // mixed values, middle aligned
        //{-1|-2|-3|-4|0|1|2|3|4|5}
        bar.setRect(x, h < 0 ? axe : axe - h, barWidth, h < 0 ? -h : h);
      }
      g.fill(bar);
      x += (barWidth + spacing1);
    }

    g.dispose();
  }

  /**
   * Computes the average for all numbers in the array.
   *
   * @param data the numbers for which the average should be computed.
   * @return the average.
   */
  private static float computeAverage(final Number[] data)
  {
    int total = 0;
    int length = 0;
    for (int index = 0; index < data.length; index++)
    {
      final Number i = data[index];
      if (i == null)
      {
        continue;
      }

      total += i.floatValue();
      length += 1;
    }

    return (total / length);
  }

}
TOP

Related Classes of org.pentaho.reporting.libraries.libsparklines.BarGraphDrawable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.