How to creat Chart in java

Are there any chart class in java to plot ACCESS  database and into a bar chart or piechart. The database is in the server and the client system must access the data from the server and plot a chart on a specifed report in java  applet

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

                   import java.awt.*;
                   import java.awt.event.*;
                   import java.awt.font.*;
                   import java.awt.geom.*;
                   import java.util.*;

                   import javax.swing.*;
                   import javax.swing.border.*;

                   public class Charts2D
                   extends JFrame

                   public Charts2D()
                   super("2D Charts");
                   setSize(720, 280);
                   getContentPane().setLayout(new GridLayout(1, 3, 10, 0));

                   int nData = 8;
                   int[] xData = new int[nData];
                   int[] yData = new int[nData];
                   for (int k=0; k<nData; k++)
                   xData[k] = k;
                   yData[k] = (int)(Math.random()*100);
                   if (k > 0)
                   yData[k] = (yData[k-1] + yData[k])/2;

                   JChart2D chart = new JChart2D(JChart2D.CHART_LINE, nData, xData,
                   yData, "Line Chart");
                   chart.setStroke(new BasicStroke(5f, BasicStroke.CAP_ROUND,
                   chart.setLineColor(new Color(0, 128, 128));

                   chart = new JChart2D(JChart2D.CHART_COLUMN,
                   nData, xData, yData, "Column Chart");
                   GradientPaint gp = new GradientPaint(0, 100,
                   Color.white, 0, 300,, true);

                   chart = new JChart2D(JChart2D.CHART_PIE, nData, xData,
                   yData, "Pie Chart");
                   ImageIcon icon = new ImageIcon("hubble.gif");

                   WindowListener wndCloser = new WindowAdapter()
                   public void windowClosing(WindowEvent e)


                   public static void main(String argv[])
                   new Charts2D();


                   class JChart2D
                   extends JPanel
                   public static final int CHART_LINE = 0;
                   public static final int CHART_COLUMN = 1;
                   public static final int CHART_PIE = 2;

                   public static final int EFFECT_PLAIN = 0;
                   public static final int EFFECT_GRADIENT = 1;
                   public static final int EFFECT_IMAGE = 2;

                   protected int m_chartType = CHART_LINE;
                   protected JLabel m_title;
                   protected ChartPanel m_chart;

                   protected int m_nData;
                   protected int[] m_xData;
                   protected int[] m_yData;
                   protected int m_xMin;
                   protected int m_xMax;
                   protected int m_yMin;
                   protected int m_yMax;
                   protected double[] m_pieData;

                   protected int    m_effectIndex = EFFECT_PLAIN;
                   protected Stroke m_stroke;
                   protected GradientPaint m_gradient;
                   protected Image  m_foregroundImage;
                   protected Color  m_lineColor =;
                   protected Color  m_columnColor =;
                   protected int    m_columnWidth = 12;
                   protected boolean m_drawShadow = false;

                   public JChart2D(int type, int nData,
                   int[] yData, String text)
                   this(type, nData, null, yData, text);

                   public JChart2D(int type, int nData, int[] xData,
                   int[] yData, String text)
                   super(new BorderLayout());
                   m_title = new JLabel(text, JLabel.CENTER);
                   add(m_title, BorderLayout.NORTH);

                   m_chartType = type;

                   if (xData==null)
                   xData = new int[nData];
                   for (int k=0; k<nData; k++)
                   xData[k] = k;
                   if (yData == null)
                   throw new IllegalArgumentException("yData can't be null");
                   if (nData > yData.length)
                   throw new IllegalArgumentException("Insufficient yData length");
                   if (nData > xData.length)
                   throw new IllegalArgumentException("Insufficient xData length");
                   m_nData = nData;
                   m_xData = xData;
                   m_yData = yData;

                   m_xMin = m_xMax = 0; // To include 0 into the interval
                   m_yMin = m_yMax = 0;
                   for (int k=0; k<m_nData; k++)
                   m_xMin = Math.min(m_xMin, m_xData[k]);
                   m_xMax = Math.max(m_xMax, m_xData[k]);
                   m_yMin = Math.min(m_yMin, m_yData[k]);
                   m_yMax = Math.max(m_yMax, m_yData[k]);
                   if (m_xMin == m_xMax)
                   if (m_yMin == m_yMax)

                   if (m_chartType == CHART_PIE)
                   double sum = 0;
                   for (int k=0; k<m_nData; k++)
                   m_yData[k] = Math.max(m_yData[k], 0);
                   sum += m_yData[k];
                   m_pieData = new double[m_nData];
                   for (int k=0; k<m_nData; k++)
                   m_pieData[k] = m_yData[k]*360.0/sum;

                   m_chart = new ChartPanel();
                   add(m_chart, BorderLayout.CENTER);

                   public void setEffectIndex(int effectIndex)
                   m_effectIndex = effectIndex;

                   public int getEffectIndex()
                   return m_effectIndex;

                   public void setStroke(Stroke stroke)
                   m_stroke = stroke;

                   public void setForegroundImage(Image img)
                   m_foregroundImage = img;

                   public Image getForegroundImage()
                   return m_foregroundImage;

                   public Stroke getStroke()
                   return m_stroke;

                   public void setGradient(GradientPaint gradient)
                   m_gradient = gradient;

                   public GradientPaint getGradient()
                   return m_gradient;

                   public void setColumnWidth(int columnWidth)
                   m_columnWidth = columnWidth;

                   public int setColumnWidth()
                   return m_columnWidth;

                   public void setColumnColor(Color c)
                   m_columnColor = c;

                   public Color getColumnColor()
                   return m_columnColor;

                   public void setLineColor(Color c)
                   m_lineColor = c;

                   public Color getLineColor()
                   return m_lineColor;

                   public void setDrawShadow(boolean drawShadow)
                   m_drawShadow = drawShadow;

                   public boolean getDrawShadow()
                   return m_drawShadow;

                   class ChartPanel
                   extends JComponent
                   int m_xMargin = 5;
                   int m_yMargin = 5;
                   int m_pieGap = 10;

                   int m_x;
                   int m_y;
                   int m_w;
                   int m_h;


                   protected void processComponentEvent(ComponentEvent e)

                   public void calcDimensions()
                   Dimension d = getSize();
                   m_x = m_xMargin;
                   m_y = m_yMargin;
                   m_w = d.width-2*m_xMargin;
                   m_h = d.height-2*m_yMargin;
                   if (m_chartType == CHART_COLUMN)
                   m_x += m_columnWidth/2;
                   m_w -= m_columnWidth;

                   public int xChartToScreen(int x)
                   return m_x + (x-m_xMin)*m_w/(m_xMax-m_xMin);

                   public int yChartToScreen(int y)
                   return m_y + (m_yMax-y)*m_h/(m_yMax-m_yMin);

                   public void paintComponent(Graphics g)
                   int x0 = 0;
                   int y0 = 0;
                   if (m_chartType != CHART_PIE)
                   x0 = xChartToScreen(0);
                   g.drawLine(x0, m_y, x0, m_y+m_h);
                   y0 = yChartToScreen(0);
                   g.drawLine(m_x, y0, m_x+m_w, y0);

                   Graphics2D g2 = (Graphics2D) g;

                   if (m_stroke != null)

                   GeneralPath path = new GeneralPath();
                   switch (m_chartType)
                   case CHART_LINE:
                   for (int k=1; k<m_nData; k++)

                   case CHART_COLUMN:
                   for (int k=0; k<m_nData; k++)
                                                           m_xMax ++;
                   int x = xChartToScreen(m_xData[k]);
                   int w = m_columnWidth;
                   int y1 = yChartToScreen(m_yData[k]);
                   int y = Math.min(y0, y1);
                   int h = Math.abs(y1 - y0);
                   Shape rc = new Rectangle2D.Double(x, y, w, h);
                   path.append(rc, false);
                                                           m_xMax --;

                   if (m_drawShadow)
                   AffineTransform s0 = new AffineTransform(
                   1.0, 0.0, 0.0, -1.0, x0, y0);
                   1.0, 0.5));
                   0.5, 0.0));
                   s0.concatenate(new AffineTransform(
                   1.0, 0.0, 0.0, -1.0, -x0, y0));
                   Shape shadow = s0.createTransformedShape(path);

                   if (m_effectIndex==EFFECT_GRADIENT && 
                   m_gradient != null)
                   else if (m_effectIndex==EFFECT_IMAGE && 
                   m_foregroundImage != null)
                   fillByImage(g2, path,0);

                   case CHART_PIE:
                   double start = 0.0;
                   double finish = 0.0;
                   int ww = m_w - 2*m_pieGap;
                   int hh = m_h - 2*m_pieGap;
                   if (m_drawShadow)
                   ww -= m_pieGap;
                   hh -= m_pieGap;

                   for (int k=0; k<m_nData; k++)
                   finish = start+m_pieData[k];
                   double f1 = Math.min(90-start, 90-finish);
                   double f2 = Math.max(90-start, 90-finish);
                   Shape shp = new Arc2D.Double(m_x, m_y, ww, hh,
                   f1, f2-f1, Arc2D.PIE);
                   double f = (f1 + f2)/2*Math.PI/180;
                   AffineTransform s1 = AffineTransform.
                   s1.translate(m_pieGap, m_pieGap);
                   Shape piece = s1.createTransformedShape(shp);
                   path.append(piece, false);
                   start = finish;

                   if (m_drawShadow)
                   AffineTransform s0 = AffineTransform.
                   getTranslateInstance(m_pieGap, m_pieGap);
                   Shape shadow = s0.createTransformedShape(path);

                   if (m_effectIndex==EFFECT_GRADIENT && 
                   m_gradient != null)
                   else if (m_effectIndex==EFFECT_IMAGE && 
                   m_foregroundImage != null)
                   fillByImage(g2, path,0);


                   protected void fillByImage(Graphics2D g2, Shape shape, int xOffset)
                   if (m_foregroundImage == null)
                   int wImg = m_foregroundImage.getWidth(this);
                   int hImg = m_foregroundImage.getHeight(this);
                   if (wImg <=0 || hImg <= 0)
                   Rectangle bounds = shape.getBounds();
                   for (int xx = bounds.x+xOffset; xx < bounds.x+bounds.width;
                   xx += wImg)
                   for (int yy = bounds.y; yy < bounds.y+bounds.height;
                   yy += hImg)
                   g2.drawImage(m_foregroundImage, xx, yy, this);

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Chapter 23. Java2D
                   In this chapter:
                   · Java2D API overview
                   · Rendering charts
                   · Rendering text strings
                   · Rendering images
                   23.1 Java2D API overview
                   Java 2 offers a very powerful new rendering model known as Java2D. This model consists of a set of classes
                   and interfaces for advanced 2D line art, text, and image rendering. Although this API is not considered a
                   part of Swing, it is closely related to Swing and may be effectively used to develop sophisticated Swing

                   Note: Packages java.awt.print (discussed in chapter 22) and com.sun.image.codec.jpeg (discussed in
                   chapter 13) are also considered part of the Java2D API.

                   This chapter includes a Java2D API overview and shows how to use this API for chart rendering, enhanced
                   label creation, and advanced image rendering. Below we briefly discuss the classes and interfaces that are
                   fundamental to the 2D API. Note, however, that a complete description of all Java2D features lies beyond
                   the scope of this book.
                   23.1.1 The Shape interface
                   abstract interface java.awt.Shape
                   This interface provides the definition for a 2D geometrical object. Most of the classes contained in the
                   java.awt.geom package implement this interface. These classes define such things as points, lines, arcs,
                   rectangles, round rectangles, ellipses, and more complex shapes such as cubic and quadratic parametric
                   curves. These geometries allow a high degree of flexibility and with them, we can create almost any shape
                   imaginable. We can render these geometries into a 2D graphics context using its draw() or fill() methods
                   (see below). We can also perform boolean operations on multiple shapes such as union, intersection,
                   exclusive or, etc. using the java.awt.geom.Area class. The geometry of each Shape's boundary is defined as
                   a path which is represented by a set of line segments and curves encapsulated in a PathIterator instance
                   (we will not discuss the details of this here).

                   Several overloaded contains() methods determine whether a given point or rectangle lies inside a Shape,
                   and the getBounds() method returns a Shape's minimum bounding rectangle.
                   23.1.2 GeneralPath
                   class java.awt.geom.GeneralPath
                   This class implements the Shape interface and represents a geometric path constructed from several line
                   segments, or quadratic and cubic curves. Particularly important is its append(Shape s, boolean connect)
                   method which provides us with a way to append one shape to another by optionally connecting their paths
                   with a line segment.

                   GeneralPath maintains a current coordinate at all times which represents the coordinate that, if we were to
                   add a line segment, would be the beginning of the added line segment. To do this we use its lineTo()
                   method passing it two floats representing the destination coordinate. Similarly, we can use its moveTo() and
                   quadTo() methods to add a point or curve to the path.
                   23.1.3 Rectangle2D
                   class java.awt.geom.Rectangle2D
                   This class serves as a superclass for three classes: the well-known java.awt.Rectangle class,
                   Rectangle2D.Double, and Rectangle2D.Float. These classes not only provide new ways to work with
                   rectangles, but also allow us to specify a rectangle's coordinates in int, float, or double form. Along with
                   Rectangle2D, the java.awt.geom package also includes a set of classes which provide new functionality to
                   familiar graphical primitives, such as Dimension2D, Line2D, and Point2D. Each of these classes allow us to
                   specify their coordinates using ints, floats, or doubles  through appropriate subclasses.
                   23.1.4 AffineTransform
                   class java.awt.geom.AffineTransform
                   This class encapsulates a general form affine transformation between two coordinate systems. This
                   transformation is essentially a coordinate transformation represented by a 3x3 matrix with an implied last
                   row ([0 0 1]) mapping each x and y in the bounding rectangle of a Shape to a new x' and y' according to the

                   x' = m00 x + m01 y + m02
                   y' = m10 x + m11 y + m12

                   The mxx's represent the first two rows of a 3x3 matrix. These formulas are quite simple to understand and
                   can be rewritten, for most operations, as the following:

                   x' = (scaleX * x) + (shearX * y) + offsetX
                   y' = (scaleY * x) + (shearY * y) + offsetY

                   Thess transformations preserve lines and parallelism (i.e. parallel lines are mapped to parallel lines). We use
                   them to perform scaling, shearing, and translation. To construct an AffineTransform we use either the double
                   or float version of the following constructor:

                       AffineTransform(m00, m10, m01, m11, m02, m12)

                   Note the order of the parameters. This directly corresponds to the columns of our matrix described above.

                   Rotation also preserves parallelism. Given an angle of rotation in radians, q :

                   x' = x*(cosq) + y*(-sinq) + offsetX
                   y' = x*(sinq) + y*(cosq) + offsetY

                   Note that (degrees * p/180) = radians.

                   The Java2D graphics context (see below) maintains a transform attribute, just as it maintains a color and
                   font attribute. Whenever we draw or fill a shape, this operation will be performed according to the current
                   state of the transform attribute. We can create an instance of AffineTransform by specifying the first two
                   rows of the matrix as described above. Alternatively, we can use static methods to create specific types of
                   transformations: getRotateInstance(), getScaleInstance(), getShearInstance(), or getTranslateInstance().
                   We can use the concatenate() method to concatenate multiple transformations successively. We can also
                   compose specific transformations with an existing AffineTransform using its rotate(), scale(), shear(), and
                   translate() methods.

                   AffineTransforms are widely used throughout the 2D API as parameters to methods requiring a
                   transformation to produce various visual effects.
                   23.1.5 The Stroke interface
                   abstract interface java.awt.Stroke
                   This interface defines only one method: createStrokedShape(Shape p), which generates a Shape that is the
                   outline of the given Shape parameter. This outline can be of various size, shape, and décor. The only
                   implementing class is BasicStroke (see below). We use Strokes to define line styles for drawing in the
                   Java2D graphics context. To set the stroke attribute of a given Graphics2D we use its setStroke() method.
                   23.1.6 BasicStroke
                   class java.awt.BasicStroke
                   This class implements the Stroke interface and defines a set of rendering attributes specifying how to render
                   the outline of a Shape. These attributes consist of line width, join style, end-cap style, and dash style:
                   The line width (often called the pen width) is the thickness measured perpendicular to its trajectory.
                   The end-cap style specifies whether round, butt, or square ends are used to render the ends of line
                   segments: CAP_ROUND, CAP_BUTT, and CAP_SQUARE.
                   The join style specifies how to render the joints between segments. This can be one of bevel, miter, or
                   round: JOIN_BEVEL, JOIN_MITER, and JOIN_ROUND.
                   The dash style defines a pattern of opaque and transparent regions rendered along a line segment.
                   23.1.7 The Paint interface
                   abstract interface java.awt.Paint
                   This interface defines how colors and color patterns may be assigned to the 2D graphics context for use in
                   drawing and filling operations. Some important implementing classes are Color, GradientPaint, and
                   TexturePaint. We use Paints to define fill patterns for filling in Shapes in the Java2D graphics context. To set
                   the paint attribute of a given Graphics2D we use its setPaint() method.
                   23.1.8 GradientPaint
                   class java.awt.GradientPaint
                   This class implements the Paint interface and renders a shape by using a linear color gradient. The gradient
                   is determined by two 2D points and two colors associated with them. The gradient can optionally be cyclical
                   which means that between both points it will cycle through shades of each color several times, rather than
                   just once. We use the Graphics2D.setPaint() method to assign a GradientPaint instance to a Graphics2D
                   object. We can then call the fill() method to fill a specified Shape with this gradient. Note that this class
                   provides an easy way to produce remarkable visual effects using only a few lines of code.
                   23.1.9 TexturePaint
                   class java.awt.TexturePaint
                   This class implements the Paint interface and is used to fill Shapes with a texture stored in a BufferedImage.
                   We use the Graphics2D.setPaint() method to assign a TexturePaint instance to a Graphics2D object. We can
                   call the fill() method to fill a specified Shape with this texture. Note that the BufferedImages used for a
                   texture are expected to be small, as a TexturePaint object makes a copy of its data and stores it internally;
                   it does not reference the provided BufferedImage. It is also important to reuse TexturePaint objects, rather
                   than create new ones, whenever possible.
                   23.1.10 Graphics2D
                   class java.awt.Graphics2D
                   This class extends the java.awt.Graphics class to provide a more sophisticated API for working with
                   geometry, transformations, colors, fill patterns and line styles, and text layout. In Java 2, the Graphics object
                   passed to a component's paint() method is really a Graphics2D object. So we can use this class in our
                   paint() implementation by simply casting our Graphics object to a Graphics2D:

                     public void paint(Graphics g)
                       Graphics2D g2 = (Graphics2D) g;
                       // Use Graphics2D ...

                   We can assign attributes to a Graphics2D instance using methods such as setTransform(), setStroke() or
                   setPaint(), as we discussed above. We can then call draw() to outline a given Shape instance using the
                   assigned Stroke, and we can call fill() to fill a given Shape with the assigned Color, GradientPaint, or
                   TexturePaint. Depending on the state of the transform attribute, Shapes will be translated, rotated, scaled,
                   or sheared appropriately as they are drawn (see AffineTransform). We can modify the current transform
                   directly with methods rotate(), scale(), shear(), and translate(). We can also assign it a new transform using
                   its setTransform() method, or compose the current transform with a given one using its transform() method.

                   A Graphics2D object can maintain preferences for specific rendering algorithms to use depending on whether
                   speed or quality is the priority. These are called rendering hints. They can be assigned using the
                   setRenderingHint() method and are stored as key/value pairs. Valid keys and values are defined in the
                   RenderingHints class. Two of these pairs are especially important to us, as the examples in this chapter will
                   always use them:

                   By setting the KEY_ANTIALIASING property to VALUE_ANTIALIAS_ON you can take advantage of a technique
                   used to render objects with smoothly blended edges (by using intermediate colors to render a border
                   between, say, black and white areas).
                   By setting the the KEY_RENDERING property to VALUE_RENDER_QUALITY, appropriate rendering algorithms
                   will always be chosen to ensure the best output quality.
                   23.1.11 GraphicsEnvironment
                   class java.awt.GraphicsEnvironment
                   This class is capable of retrieving the collection of GraphicsDevice and Font instances available to a Java
                   application on the running platform. GraphicsDevices can reside on the local machine or any number of
                   remote machines. A GraphicsDevice instance describes, surprisingly, a graphics device such as a screen or

                   Recall from chapter 2 that we normally reference GraphicsEnvironment to retrieve the names of all available

                     String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().
                   23.1.12 BufferedImage
                   class java.awt.image.BufferedImage
                   This class represents an Image stored in memory providing methods for storing, interpreting, and rendering
                   pixel data. It is used widely throughout the 2D API and we've already seen it in chapters 13 and 22. In
                   particular, you can create a BufferedImage, retrieve its associated Graphics2D instance to render into,
                   perform the rendering, and use the result as an image for, among other things, painting directly into
                   another graphics context (we used this technique in the construction of our print preview component). This
                   is also similar to how RepaintManager handles the buffering of all Swing components, as we discussed in
                   chapter 2.
                   23.1.13 FontRenderContext
                   class java.awt.font.FontRenderContext
                   Instances of this class encapsulate information needed to correctly measure text. This includes rendering
                   hints and target device specific information such as resolution (dots-per-inch).  A FontRenderContext
                   instance representing the current state of the 2D graphics context can be retrieved using Graphics2D's
                   getFontRenderContext() method. FontRenderContext is usually used in association with text formatting
                   using Fonts and TextLayouts.
                   23.1.14 TextLayout
                   class java.awt.font.TextLayout
                   Instances of this class represent an immutable graphical representation of styled text--that is, they cannot
                   change (this class does not contain any set accessors). Only new instances can be created, and a
                   FontRenderContext instance is required to do this. We render a TextLayout in the 2D graphcis context using
                   that TextLayout's draw() method. This class is very powerful and supports such things as hit detection,
                   which will return the character a mouse press occurs on, as well as support for bi-directional text and split
                   cursors. A particularly noteworthy method is getOutline(AffineTransform tx), which returns a Shape instance
                   outlining the text.
                   23.2 Rendering charts
                   In this section we'll demonstrate the advantages of using the Java2D API for rendering charts. The following
                   example introduces a custom component which is capable of rendering line graphs, bar charts, and pie
                   charts using strokes, color gradients, and background images. This application demonstrates how to build
                   such charts taking into account issues such as axis positioning and scaling based on the given coordinate
                   data. Be prepared for a bit of math.

                   Understanding the Code (Above example)
                   Class Charts2D
                   This class provides the frame encompassing this example. It creates an array of equidistant x-coordinates
                   and random y-coordinates to be drawn in the charts. Three instances of our custom JChart2D class (see
                   below) are created and placed in the frame using a GridLayout. The methods used to provide setup and
                   initialization for our chart are built into the JChart2D class and will be explained below.
                   Class JChart2D
                   Several constants are defined for use as the available chart type and visual effect options:
                   int CHART_LINE: specifies a line chart.
                   int CHART_COLUMN: specifies a column chart.
                   int CHART_PIE: specifies a pie chart.
                   int EFFECT_PLAIN: use no visual effects (homogeneous chart).
                   int EFFECT_GRADIENT: use a color gradient to fill the chart.
                   int EFFECT_IMAGE: use an image to fill the chart.

                   Several instance variables are defined to hold data used by this class:
                   JLabel m_title: label used to display a chart's title.
                   ChartPanel m_chart: custom component used to display a chart's body (see below).
                   int m_nData: number of points in the chart.
                   int[] m_xData: array of x-coordinates in the chart.
                   int[] m_yData: array of y-coordinates in the chart.
                   int m_xMin: minimum x-coordinate.
                   int m_xMax: maximum x-coordinate.
                   int m_yMin: minimum y-coordinate.
                   int m_yMax: maximum y-coordinate.
                   double[] m_pieData: angles for each piece of the pie chart.
                   int m_chartType: maintains the chart's type (one of the constants listed above).
                   int m_effectIndex: maintains the chart's effect index (one of the constants listed above).
                   Stroke m_stroke: stroke instance used to outline the chart.
                   GradientPaint m_gradient: color gradient used to fill the chart (this only takes effect when m_effectIndex is
                   set to EFFECT_GRADIENT).
                   Image m_foregroundImage: image used to fill the chart (this only takes effect when m_effectIndex is set to
                   Color m_lineColor: color used to outline the chart.
                   Color m_columnColor: color used to fill the chart (this only takes effect when m_effectIndex is set to
                   EFFECT_PLAIN -- this is its default setting).
                   int m_columnWidth: width of columns in the column chart.
                   boolean m_drawShadow: flag to draw a shadow for column or pie chart.

                   Two constructors are provided in the JChart2D class. The first one takes four parameters and simply calls
                   the second, passing it the given parameters and using a null value for a fifth. This second constructor is
                   where a JChart2D is actually created and its five parameters are:
                   int type: the type of this chart (CHART_LINE, CHART_COLUMN, or CHART_PIE).
                   int nData: number of data points in this chart.
                   int[] xData: an array of x-coordinates for this chart (may be null -- this is passed as null from the first
                   int[] yData: an array of y-coordinates for this chart.
                   String text: this chart's title.

                   The constructor validates the input data and initializes all instance variables. In the case of a pie chart, an
                   array, m_pieData, is created, which contains sectors with angles normalized to 360 degrees (the sum value
                   used here was calculated previous to this code as the sum of all m_yData[] values):

                        m_pieData = new double[m_nData];
                        for (int k=0; k<m_nData; k++)
                          m_pieData[k] = m_yData[k]*360.0/sum;

                   This chart component extends JPanel and contains two child components managed using a BorderLayout:
                   JLabel m_title, which displays the chart's title in the NORTH region, and an instance of our custom
                   ChartPanel component, m_chart, which is placed in the CENTER region.

                   The rest of the code for this class consists of set/get methods supporting instance variables declared in this
                   class and does not require further explanation.
                   Class JChart2D.ChartPanel
                   This inner class extends JComponent and represents the custom component that is actually responsible
                   for  rendering our charts. Several instance variables are declared:
                   int m_xMargin: the left and right margin size of the rendering area.
                   int m_yMargin: the top and bottom margin size of the rendering area.
                   int m_pieGap: radial shift for pieces of pie (i.e. spacing between each).
                   int m_x: left coordinate of the rendering area.
                   int m_y: top coordinate of the rendering area.
                   int m_w: width of the rendering area.
                   int m_h: height of the rendering area.

                   The ChartPanel constructor enables the processing of component resize events. When such an event
                   occurs, the processComponentEvent() method triggers a call to calcDimensions() (note that this event will
                   normally be generated when ChartPanel is added to a container for the first time). This method retrieves the
                   current component's size, calculates the coordinates of the rendering area, and stores them in the
                   appropriate instance variables listed above. In the case of a column chart, we offset the rendering area by
                   an additional half of the column width, and then shrink it by a full column width. Otherwise, the first and the
                   last columns will be rendered on top of the chart's border.

                   Methods xChartToScreen() and yChartToScreen() calculate screen coordinates from chart coordinates as
                   illustrated in figure 23.2. We need to scale the chart data so the chart will occupy the entire component
                   region, taking into account the margins. To get the necessary scaling ratios we divide the dimensions of the
                   chart component (minus the margins) by the difference between max and min values of the chart data.
                   These methods are used in rendering the line and column charts because they are based on coordinate
                   data. The only sizing information the pie chart needs is m_w and m_h, as it does not rely on coordinate
                   The paintComponent() method performs the actual chart rendering. The coordinate axes are drawn first for
                   line and column charts. Then we cast the Graphics instance to a Graphics2D so we have access to Java2D
                   features. As we discussed earlier, we use two rendering hints and assign them with the setRenderingHint()
                   method: anti-aliasing and the preference to render quality over speed. If the m_stroke instance variable has
                   been initialized, the Graphics2D stroke attribute is set using the setStroke() method. The rest of the
                   paintComponent() method is placed into a switch block with cases for each chart type. Before the switch
                   block is entered we create a GeneralPath which we will use to construct each chart using the methods we
                   described in section 23.1.2.

                   The line chart is the simplest case. It is drawn as a broken line through the array of points representing the
                   chart data. First we start the GeneralPath out by passing the first coordinate of data using moveTo().
                   Then  we iterate through the chart data adding lines to the path using its lineTo() method. Once we've done
                   this we are ready to render it and use the Graphics2D  draw() method to do so.

                   Note: The Java2D API provides ways to draw quadratic and cubic curves passing through 3 and 4 given
                   points respectively. Unfortunately this functionality is not suitable for drawing a smooth line chart with

                   The column chart is drawn as a set of vertical bars with a common baseline corresponding to the 0-value of
                   the chart, y0 (note that this value is always included in the [m_yMin, m_yMax] interval). The GeneralPath
                   instance accumulates these bars as Rectangle2D.Double instances using its append() method, passing false
                   for the  line connection option.

                   If the m_drawShadow flag is set, the next step forms and draws a shadow from these bars, which should
                   be viewed as standing vertically. AffineTransform s0 is constructed to accomplish this in four steps:
                   1. Transform from screen coordinates to chart coordinates.
                   2. Scale y-axis by a factor of 0.5.
                   3. Shear x-axis by a factor of 1.0.
                   4. Transform chart coordinates back to screen coordinates.

                   As soon as this AffineTransform is constructed, we create a corresponding transformed version of our path
                   Shape using AffineTransform's createTransformedShape() method. We then set the current color to gray and
                   render it into the 2D graphics context using the fill() method. Finally the set of bars is drawn on the screen.
                   Depending on the m_effectIndex setting we fill this shape with the gradient color, image (by calling our
                   custom fillByImage() method), or with a solid color.

                   The pie chart is drawn as pieces of a circle with a common center. The larger the chart's value is for a given
                   point, the larger the corresponding angle of that piece is. For an interesting resemblance with a cut pie, all
                   pieces are shifted apart from the common center in the radial direction. To draw such a pie we first build
                   each piece by iterating through the chart's data. Using class Arc2D.Double with its PIE setting provides a
                   convenient way to build a slice of pie. We then translate this slice away from the pie's center in the radial
                   direction using an AffineTransform and its createTransformShape() method. Each resulting shape is
                   appended to our GeneralPath instance.

                   If the m_drawShadow flag is set, we form and draw a shadow from these pieces. Since this chart can be
                   viewed as laying on a flat surface, the shadow has the same shape as the chart itself, but is translated in
                   the south-east direction. Finally the set of pie pieces is drawn on the screen using the selected visual effect.
                   Since at this point we operate with the chart as a single Shape (remember a GeneralPath is a Shape), the
                   code is the same as for the column chart.

                   The custom fillByImage() method uses the given Shape instance's bounds as the Graphics2D clipping area,
                   and, in a doubly nested for loop, fills this region using our previously assigned m_foregroundImage. (Note
                   that the third parameter to this method, int xOffset, is used for horizontal displacement which we do not
                   make use of in this example. However, we will see this method again in the nex
Or go to : and download the chapter 23 with all examples.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.