View Javadoc
1   /******************************************************************************
2    * RatingGraphPanel.java - The toolbar ratings graph widget
3    * $Id$
4    * 
5    * BuckoFIBS - Backgammon by BuckoSoft
6    * Copyright© 2009,2010 - Dick Balaska - BuckoSoft, Corp.
7    * 
8    * $Log$
9    * Revision 1.3  2010/03/03 13:12:21  inim
10   * Replaced (c) sign in comment mangled by CVS default encoding back to UTF-8
11   *
12   * Revision 1.2  2010/03/03 12:19:49  inim
13   * Moved source to UTF8 encoding from CP1252 encoding. To this end all source files' (c) message was updated to "Copyright© 2009,2010 - Dick Balaska - BuckoSoft, Corp.". This replaces the (c) sign to UTF8, and adds the new year 2010.
14   *
15   * Revision 1.1  2010/02/04 05:57:53  inim
16   * Mavenized project folder layout
17   *
18   * Revision 1.6  2010/01/29 23:13:31  dick
19   * public redraw() calls repaint().
20   * Cleanup when only 1 data point.
21   *
22   * Revision 1.5  2010/01/26 19:12:00  dick
23   * Configurable how many data points in the graph.
24   *
25   * Revision 1.4  2009/03/12 15:29:28  dick
26   * Change the size of the game points depending on how many pixels per game we get.
27   *
28   * Revision 1.3  2009/02/23 09:51:18  dick
29   * Draw the marker dots at each match.
30   *
31   * Revision 1.2  2009/02/22 07:06:24  dick
32   * Display the ratings text in the panel.
33   *
34   * Revision 1.1  2009/02/21 17:34:56  dick
35   * The toolbar ratings graph widget.
36   *
37   */
38  
39  /* 
40   * This program is free software: you can redistribute it and/or modify
41   * it under the terms of the GNU General Public License as published by
42   * the Free Software Foundation, either version 3 of the License, or
43   * (at your option) any later version.
44   *
45   * This program is distributed in the hope that it will be useful,
46   * but WITHOUT ANY WARRANTY; without even the implied warranty of
47   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48   * GNU General Public License for more details.
49   *
50   * You should have received a copy of the GNU General Public License
51   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
52   *
53   * The Original Code is BuckoFIBS, <http://www.buckosoft.com/BuckoFIBS/>.
54   * The Initial Developer of the Original Code is Dick Balaska and BuckoSoft, Corp.
55   * 
56   */
57  package com.buckosoft.fibs.BuckoFIBS.gui;
58  
59  import java.awt.Color;
60  import java.awt.Dimension;
61  import java.awt.Font;
62  import java.awt.FontMetrics;
63  import java.awt.Graphics;
64  
65  import javax.swing.JPanel;
66  
67  import com.buckosoft.fibs.domain.config.RatingGraphConfig;
68  
69  /** The toolbar ratings graph widget
70   * @author Dick Balaska
71   * @since 2009/02/20
72   * @version $Revision$ <br> $Date$
73   * @see <a href="http://cvs.buckosoft.com/Projects/BuckoFIBS/BuckoFIBS/src/com/buckosoft/fibs/BuckoFIBS/gui/RatingGraphPanel.java">cvs RatingGraphPanel.java</a>
74   */
75  public class RatingGraphPanel extends JPanel {
76  	private	final static boolean DEBUG = false;
77  	private static final long serialVersionUID = 1L;
78  	private	Font	font = new Font("Arial", Font.PLAIN, 10);
79  	private Color	lineColor = new Color(213,215,5);
80  	
81  	protected class Specs {
82  		int w;
83  		int h;
84  	}
85  	private	Specs bs = new Specs();  //  @jve:decl-index=0:
86  
87  	private	double data[] = new double[] { 1500.0, 1503.0, 1505.0 };
88  	private	int	xpoints[] = new int[data.length];
89  	private	int	ypoints[] = new int[data.length];
90  
91  	private	RatingGraphConfig config = new RatingGraphConfig();
92  
93  	/** Create a new RatingGraphPanel 
94  	 */
95  	public RatingGraphPanel() {
96  		super();
97  		initialize();
98  	}
99  
100 	/** Set the data points to use in the graph. <br>
101 	 * This is an array of ratings. <br>
102 	 * Setting the data causes the graph to redraw itself.
103 	 * @param data
104 	 */
105 	public void setData(double[] data) {
106 		this.data = data;
107 		xpoints = new int[data.length];
108 		ypoints = new int[data.length];
109 		this.repaint();
110 	}
111 
112 	/** Force a redraw of the graph.
113 	 * (Maybe the config changed)
114 	 */
115 	public void redraw() {
116 		this.repaint();
117 	}
118 
119 	public void setConfig(RatingGraphConfig ratingGraphConfig) {
120 		this.config = ratingGraphConfig;
121 	}
122 
123 	/**
124 	 * This method initializes this
125 	 * 
126 	 */
127 	private void initialize() {
128         this.setSize(new Dimension(216, 61));
129 	}
130 
131 	/** Override JComponent's paint(Graphics)
132 	 * @param g The Graphics from Swing
133 	 */
134 	public void paint(Graphics g) {
135 		super.paint(g);
136 		
137 		int i,j;
138 		int	x,y;
139 		double high, low, range;
140 		double d;
141 		bs.w = this.getWidth();
142 		bs.h = this.getHeight();
143 		g.setColor(Color.black);
144 		g.fillRect(0, 0, bs.w, bs.h);
145 		
146 		if (data == null || data.length == 0)
147 			return;
148 		
149 		// determine the first and last data points
150 		int first = 0;
151 		int last = data.length;
152 		if (config.getType() == RatingGraphConfig.Type.displayLastXMatches) {
153 			if (last > config.getMatchCount())
154 				first = last - config.getMatchCount();
155 		}
156 			
157 		// pixels per segment
158 		int pps = bs.w / (last-first);
159 		if (DEBUG)
160 			System.out.println("RatingGraph: w="  + bs.w + " numPoints=" + (last-first) + " pps=" + pps);
161 		g.setColor(lineColor);
162 		if (last == 1) {
163 			g.drawLine(0, bs.h/2, bs.w, bs.h/2);
164 			low = -100000;
165 			high = 20000;
166 			range = high - low;
167 		} else {
168 			xpoints = new int[last-first];
169 			ypoints = new int[last-first];
170 			low = data[first];
171 			high = low;
172 			for (i=first; i<last; i++) {
173 				if (low > data[i])
174 					low = data[i];
175 				if (high < data[i])
176 					high = data[i];
177 			}
178 			range = high - low;
179 			for (i=first, j=0; i<last; i++, j++) {
180 				//double d;
181 				if (i == 0)
182 					xpoints[j] = 0;
183 				else if (last-first-1 == 0)
184 					xpoints[j] = bs.w;
185 				else
186 					xpoints[j] = j * bs.w / (last-first-1);
187 				ypoints[j] = (int)(bs.h-((data[i]-low)*bs.h / range));
188 			}
189 			g.drawPolyline(xpoints, ypoints, xpoints.length);
190 			
191 			g.setColor(Color.white);
192 			g.setFont(font);
193 			FontMetrics fm = g.getFontMetrics();
194 			String s = "" + low; 
195 			//int sw = fm.stringWidth(s);
196 			x = 0;
197 			y = bs.h-1; 
198 			g.drawString(s, x, y);
199 			s = "" + high;
200 			y = 0 + fm.getAscent()-1;
201 			g.drawString(s, x, y);
202 		}
203 		g.setColor(Color.white);
204 		g.setFont(font);
205 		FontMetrics fm = g.getFontMetrics();
206 		d = data[last-1];
207 		String s = "" + d;
208 		int sw = fm.stringWidth(s);
209 		x = bs.w - sw;
210 		double mid = low + range/2;
211 		if (d > mid)
212 			y = bs.h*3/4 + fm.getAscent()/2;
213 		else
214 			y = bs.h*1/4 + fm.getAscent()/2;
215 		g.drawString(s, x, y);
216 		
217 		if (data.length > 1) {
218 			for (i=first, j=0; i<last; i++, j++) {
219 				Color c = Color.green;
220 				if (i>0 && data[i] < data[i-1])
221 					c = Color.red;
222 				g.setColor(c);
223 				if (pps > 7)
224 					g.drawRect(xpoints[j]-1, ypoints[j]-1, 3, 3);
225 				else if (pps > 3)
226 					g.drawRect(xpoints[j]-1, ypoints[j]-1, 2, 2);
227 				else
228 					g.drawRect(xpoints[j]-1, ypoints[j]-1, 1, 1);
229 	
230 			}
231 		}
232 	}	
233 
234 }  //  @jve:decl-index=0:visual-constraint="10,10"