KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > analyzer > charts > ChartMaker


1 /*
2  * ChartDrawer.java
3  *
4  * Created on May 9, 2005, 4:21 PM
5  */

6
7 package analyzer.charts;
8
9 import java.awt.BasicStroke JavaDoc;
10 import java.awt.BorderLayout JavaDoc;
11 import java.awt.Color JavaDoc;
12 import java.awt.Dimension JavaDoc;
13 import java.awt.GradientPaint JavaDoc;
14 import java.awt.Graphics JavaDoc;
15 import java.awt.Graphics2D JavaDoc;
16 import java.awt.GridLayout JavaDoc;
17 import java.awt.Image JavaDoc;
18 import java.awt.Rectangle JavaDoc;
19 import java.awt.RenderingHints JavaDoc;
20 import java.awt.Shape JavaDoc;
21 import java.awt.Stroke JavaDoc;
22 import java.awt.event.ComponentEvent JavaDoc;
23 import java.awt.event.WindowAdapter JavaDoc;
24 import java.awt.event.WindowEvent JavaDoc;
25 import java.awt.event.WindowListener JavaDoc;
26 import java.awt.geom.AffineTransform JavaDoc;
27 import java.awt.geom.Arc2D JavaDoc;
28 import java.awt.geom.GeneralPath JavaDoc;
29 import java.awt.geom.Rectangle2D JavaDoc;
30
31 import javax.swing.ImageIcon JavaDoc;
32 import javax.swing.JComponent JavaDoc;
33 import javax.swing.JFrame JavaDoc;
34 import javax.swing.JLabel JavaDoc;
35 import javax.swing.JPanel JavaDoc;
36
37 public class ChartMaker extends JPanel JavaDoc {
38     public static final int LineChart = 0;
39     
40     public static final int ColumnChart = 1;
41     
42     public static final int PieChart = 2;
43     
44     public static final int PLainEffect = 0;
45     
46     public static final int Gradientffect = 1;
47     
48     public static final int ImageEffect = 2;
49     
50     protected int m_chartType = LineChart;
51     
52     protected JLabel JavaDoc titleLabel;
53     
54     protected ChartPanel chartPanel;
55     
56     protected int dataLength;
57     
58     protected int[] xData;
59     
60     protected int[] yData;
61     
62     protected int xMin;
63     
64     protected int xMax;
65     
66     protected int yMin;
67     
68     protected int yMax;
69     
70     protected double[] pieData;
71     
72     protected int m_effectIndex = PLainEffect;
73     
74     protected Stroke JavaDoc stroke;
75     
76     protected GradientPaint JavaDoc gradient;
77     
78     protected Image JavaDoc foregroundImage;
79     
80     protected Color JavaDoc lineColor = Color.black;
81     
82     protected Color JavaDoc columnColor = Color.blue;
83     
84     protected int columnWidth = 12;
85     
86     protected boolean drawShadow = false;
87     
88     public ChartMaker(int type, int nData, int[] yData, String JavaDoc text) {
89         this(type, nData, null, yData, text);
90     }
91     
92     public ChartMaker(int type, int nData, int[] xD, int[] yD, String JavaDoc text) {
93         super(new BorderLayout JavaDoc());
94         setBackground(Color.white);
95         titleLabel = new JLabel JavaDoc(text, JLabel.CENTER);
96         add(titleLabel, BorderLayout.NORTH);
97         
98         m_chartType = type;
99         
100         if (xData == null) {
101             xData = new int[nData];
102             for (int k = 0; k < nData; k++)
103                 xData[k] = k;
104         }
105         if (yD == null)
106             throw new IllegalArgumentException JavaDoc("yData can't be null");
107         if (nData > yD.length)
108             throw new IllegalArgumentException JavaDoc("Insufficient yData length");
109         if (nData > xD.length)
110             throw new IllegalArgumentException JavaDoc("Insufficient xData length");
111         dataLength = nData;
112         xData = xD;
113         yData = yD;
114         
115         xMin = xMax = 0; // To include 0 into the interval
116
yMin = yMax = 0;
117         for (int k = 0; k < dataLength; k++) {
118             xMin = Math.min(xMin, xData[k]);
119             xMax = Math.max(xMax, xData[k]);
120             yMin = Math.min(yMin, yData[k]);
121             yMax = Math.max(yMax, yData[k]);
122         }
123         if (xMin == xMax)
124             xMax++;
125         if (yMin == yMax)
126             yMax++;
127         
128         if (m_chartType == PieChart) {
129             double sum = 0;
130             for (int k = 0; k < dataLength; k++) {
131                 yData[k] = Math.max(yData[k], 0);
132                 sum += yData[k];
133             }
134             pieData = new double[dataLength];
135             for (int k = 0; k < dataLength; k++)
136                 pieData[k] = yData[k] * 360.0 / sum;
137         }
138         
139         chartPanel = new ChartPanel();
140         add(chartPanel, BorderLayout.CENTER);
141     }
142     
143     public void setEffectIndex(int effectIndex) {
144         m_effectIndex = effectIndex;
145         repaint();
146     }
147     
148     public int getEffectIndex() {
149         return m_effectIndex;
150     }
151     
152     public void setStroke(Stroke JavaDoc s) {
153         stroke = s;
154         chartPanel.repaint();
155     }
156     
157     public void setForegroundImage(Image JavaDoc img) {
158         foregroundImage = img;
159         repaint();
160     }
161     
162     public Image JavaDoc getForegroundImage() {
163         return foregroundImage;
164     }
165     
166     public Stroke JavaDoc getStroke() {
167         return stroke;
168     }
169     
170     public void setGradient(GradientPaint JavaDoc g) {
171         gradient = g;
172         repaint();
173     }
174     
175     public GradientPaint JavaDoc getGradient() {
176         return gradient;
177     }
178     
179     public void setColumnWidth(int c) {
180         columnWidth = c;
181         chartPanel.calcDimensions();
182         chartPanel.repaint();
183     }
184     
185     public int setColumnWidth() {
186         return columnWidth;
187     }
188     
189     public void setColumnColor(Color JavaDoc c) {
190         columnColor = c;
191         chartPanel.repaint();
192     }
193     
194     public Color JavaDoc getColumnColor() {
195         return columnColor;
196     }
197     
198     public void setLineColor(Color JavaDoc c) {
199         lineColor = c;
200         chartPanel.repaint();
201     }
202     
203     public Color JavaDoc getLineColor() {
204         return lineColor;
205     }
206     
207     public void setDrawShadow(boolean d) {
208         drawShadow = d;
209         chartPanel.repaint();
210     }
211     
212     public boolean getDrawShadow() {
213         return drawShadow;
214     }
215     
216     class ChartPanel extends JComponent JavaDoc {
217         int xMargin = 5;
218         
219         int yMargin = 5;
220         
221         int pieGap = 10;
222         
223         int m_x;
224         
225         int m_y;
226         
227         int m_w;
228         
229         int m_h;
230         
231         ChartPanel() {
232             enableEvents(ComponentEvent.COMPONENT_RESIZED);
233         }
234         
235         protected void processComponentEvent(ComponentEvent JavaDoc e) {
236             calcDimensions();
237         }
238         
239         public void calcDimensions() {
240             Dimension JavaDoc d = getSize();
241             m_x = xMargin;
242             m_y = yMargin;
243             m_w = d.width - 2 * xMargin;
244             m_h = d.height - 2 * yMargin;
245             if (m_chartType == ColumnChart) {
246                 m_x += columnWidth / 2;
247                 m_w -= columnWidth;
248             }
249         }
250         
251         public int xChartToScreen(int x) {
252             return m_x + (x - xMin) * m_w / (xMax - xMin);
253         }
254         
255         public int yChartToScreen(int y) {
256             return m_y + (yMax - y) * m_h / (yMax - yMin);
257         }
258         
259         public void paintComponent(Graphics JavaDoc g) {
260             int x0 = 0;
261             int y0 = 0;
262             if (m_chartType != PieChart) {
263                 g.setColor(Color.black);
264                 x0 = xChartToScreen(0);
265                 g.drawLine(x0, m_y, x0, m_y + m_h);
266                 y0 = yChartToScreen(0);
267                 g.drawLine(m_x, y0, m_x + m_w, y0);
268             }
269             
270             Graphics2D JavaDoc g2 = (Graphics2D JavaDoc) g;
271             g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
272                     RenderingHints.VALUE_ANTIALIAS_ON);
273             g2.setRenderingHint(RenderingHints.KEY_RENDERING,
274                     RenderingHints.VALUE_RENDER_QUALITY);
275             
276             if (stroke != null)
277                 g2.setStroke(stroke);
278             
279             GeneralPath JavaDoc path = new GeneralPath JavaDoc();
280             switch (m_chartType) {
281                 case LineChart:
282                     g2.setColor(lineColor);
283                     path.moveTo(xChartToScreen(xData[0]),
284                             yChartToScreen(yData[0]));
285                     for (int k = 1; k < dataLength; k++)
286                         path.lineTo(xChartToScreen(xData[k]),
287                                 yChartToScreen(yData[k]));
288                     g2.draw(path);
289                     break;
290                     
291                 case ColumnChart:
292                     for (int k = 0; k < dataLength; k++) {
293                         xMax++; int x = xChartToScreen(xData[k]);
294                         int w = columnWidth;
295                         int y1 = yChartToScreen(yData[k]);
296                         int y = Math.min(y0, y1);
297                         int h = Math.abs(y1 - y0);
298                         Shape JavaDoc rc = new Rectangle2D.Double JavaDoc(x, y, w, h);
299                         path.append(rc, false);
300                         xMax--;
301                     }
302                     
303                     if (drawShadow) {
304                         AffineTransform JavaDoc s0 = new AffineTransform JavaDoc(1.0, 0.0, 0.0,
305                                 -1.0, x0, y0);
306                         s0.concatenate(AffineTransform.getScaleInstance(1.0, 0.5));
307                         s0.concatenate(AffineTransform.getShearInstance(0.5, 0.0));
308                         s0.concatenate(new AffineTransform JavaDoc(1.0, 0.0, 0.0, -1.0,
309                                 -x0, y0));
310                         g2.setColor(Color.gray);
311                         Shape JavaDoc shadow = s0.createTransformedShape(path);
312                         g2.fill(shadow);
313                     }
314                     
315                     if (m_effectIndex == Gradientffect && gradient != null) {
316                         g2.setPaint(gradient);
317                         g2.fill(path);
318                     } else if (m_effectIndex == ImageEffect
319                             && foregroundImage != null)
320                         fillByImage(g2, path, 0);
321                     else {
322                         g2.setColor(columnColor);
323                         g2.fill(path);
324                     }
325                     g2.setColor(lineColor);
326                     g2.draw(path);
327                     break;
328                     
329                 case PieChart:
330                     double start = 0.0;
331                     double finish = 0.0;
332                     int ww = m_w - 2 * pieGap;
333                     int hh = m_h - 2 * pieGap;
334                     if (drawShadow) {
335                         ww -= pieGap;
336                         hh -= pieGap;
337                     }
338                     
339                     for (int i = 0; i < dataLength; i++) {
340                         finish = start + pieData[i];
341                         double f1 = Math.min(90 - start, 90 - finish);
342                         double f2 = Math.max(90 - start, 90 - finish);
343                         Shape JavaDoc shp = new Arc2D.Double JavaDoc(m_x, m_y, ww, hh, f1, f2 - f1,
344                                 Arc2D.PIE);
345                         double f = (f1 + f2) / 2 * Math.PI / 180;
346                         AffineTransform JavaDoc s1 = AffineTransform.getTranslateInstance(
347                                 pieGap * Math.cos(f), -pieGap * Math.sin(f));
348                         s1.translate(pieGap, pieGap);
349                         Shape JavaDoc piece = s1.createTransformedShape(shp);
350                         path.append(piece, false);
351                         start = finish;
352                     }
353                     
354                     if (drawShadow) {
355                         AffineTransform JavaDoc s0 = AffineTransform.getTranslateInstance(
356                                 pieGap, pieGap);
357                         g2.setColor(Color.gray);
358                         Shape JavaDoc shadow = s0.createTransformedShape(path);
359                         g2.fill(shadow);
360                     }
361                     
362                     if (m_effectIndex == Gradientffect && gradient != null) {
363                         g2.setPaint(gradient);
364                         g2.fill(path);
365                     } else if (m_effectIndex == ImageEffect
366                             && foregroundImage != null)
367                         fillByImage(g2, path, 0);
368                     else {
369                         g2.setColor(columnColor);
370                         g2.fill(path);
371                     }
372                     
373                     g2.setColor(lineColor);
374                     g2.draw(path);
375                     break;
376             }
377         }
378         
379         protected void fillByImage(Graphics2D JavaDoc g2, Shape JavaDoc shape, int xOffset) {
380             if (foregroundImage == null)
381                 return;
382             int wImg = foregroundImage.getWidth(this);
383             int hImg = foregroundImage.getHeight(this);
384             if (wImg <= 0 || hImg <= 0)
385                 return;
386             g2.setClip(shape);
387             Rectangle JavaDoc bounds = shape.getBounds();
388             for (int i = bounds.x + xOffset; i < bounds.x + bounds.width; i += wImg)
389                 for (int j = bounds.y; j < bounds.y + bounds.height; j += hImg)
390                     g2.drawImage(foregroundImage, i, j, this);
391         }
392     }
393 }
394
Popular Tags