001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.web.client.chart; 017 018import com.google.gwt.widgetideas.graphics.client.Color; 019import com.google.gwt.widgetideas.graphics.client.GWTCanvas; 020import com.smartgwt.client.types.Alignment; 021import com.smartgwt.client.types.VerticalAlignment; 022import com.smartgwt.client.util.Format; 023import com.smartgwt.client.widgets.Canvas; 024import com.smartgwt.client.widgets.Label; 025import com.smartgwt.client.widgets.layout.HLayout; 026import com.smartgwt.client.widgets.layout.VLayout; 027 028/** 029 * 030 * @author kulikov 031 */ 032public class Chart extends VLayout { 033 034 private final static int LABEL_SIZE = 30; 035 private final static int Y_SCALE = 10; 036 037 private YAxis yAxis = new YAxis(); 038 private XAxis xAxis = new XAxis(); 039 040 private int X, Y; 041 042 private ViewPort viewPort = new ViewPort(); 043 private GWTCanvas canvas; 044 045 /** 046 * Creates chart with given title. 047 * 048 * @param title chart's title. 049 */ 050 public Chart(String title) { 051 setWidth100(); 052 setHeight100(); 053 054 init(); 055 } 056 057 public final void init() { 058 Title title = new Title(""); 059 title.setWidth100(); 060 title.setHeight(30); 061 addMember(title); 062 063 HLayout layout = new HLayout(); 064 layout.setWidth100(); 065 layout.setHeight100(); 066 067 layout.addMember(yAxis); 068 layout.addMember(viewPort); 069 070 addMember(layout); 071 addMember(xAxis); 072 addMember(new Footer()); 073 } 074 075 public void drawChart(String[] xl, double[] x, double[] y1, double[] y2, double[] y3) { 076 viewPort.drawChart(xl, x, y1, y2, y3); 077 } 078 079 080 private class Title extends VLayout { 081 public Title(String title) { 082 setContents(title); 083 } 084 } 085 086 private class Footer extends VLayout { 087 public Footer() { 088 HLayout layout = new HLayout(); 089 addMember(layout); 090 091 Label strut = new Label(); 092 strut.setWidth(LABEL_SIZE); 093 094 Label min = new Label("<span style=\"color:red\">Min</span>"); 095 Label max = new Label("<span style=\"color:blue\">Max</span>"); 096 Label avg = new Label("<span style=\"color:green\">Average</span>"); 097 098 layout.addMember(strut); 099 layout.addMember(min); 100 layout.addMember(max); 101 layout.addMember(avg); 102 } 103 } 104 105 106 /** 107 * YAxis. 108 */ 109 private class YAxis extends VLayout { 110 111 public YAxis() { 112 setWidth(LABEL_SIZE); 113 setHeight100(); 114 } 115 116 private void clean() { 117 Canvas[] members = this.getMembers(); 118 for (int i = 0; i < members.length; i++) { 119 this.removeMember(members[i]); 120 } 121 } 122 123 public void drawLabels(String[] x) { 124 clean(); 125 int j = x.length - 1; 126 for (int i = 0; i < x.length; i++) { 127 addMember(new YLabel(x[j--])); 128 } 129 } 130 } 131 132 /** 133 * Label for Y axis. 134 * 135 */ 136 private class YLabel extends Label { 137 138 public YLabel(String v) { 139 setWidth100(); 140 setHeight100(); 141 setContents(v); 142 setAlign(Alignment.CENTER); 143 setLayoutAlign(Alignment.CENTER); 144 setLayoutAlign(VerticalAlignment.BOTTOM); 145 setValign(VerticalAlignment.BOTTOM); 146 } 147 } 148 149 private class XAxis extends HLayout { 150 151 public XAxis() { 152 setHeight(LABEL_SIZE); 153 setWidth100(); 154 } 155 156 private void clean() { 157 Canvas[] members = this.getMembers(); 158 for (int i = 0; i < members.length; i++) { 159 this.removeMember(members[i]); 160 } 161 } 162 163 public void drawLabels(String[] x) { 164 clean(); 165 166 Label strut = new Label(); 167 strut.setWidth(LABEL_SIZE); 168 strut.setHeight(LABEL_SIZE); 169 170 addMember(strut); 171 172 for (int i = 0; i < x.length; i++) { 173 addMember(new XLabel(x[i])); 174 } 175 } 176 } 177 178 private class XLabel extends Label { 179 public XLabel(String v) { 180 setWidth100(); 181 setHeight100(); 182 setContents(v); 183 setAlign(Alignment.LEFT); 184 setLayoutAlign(Alignment.LEFT); 185 } 186 } 187 188 private class ViewPort extends HLayout { 189 190 private final Color COLOR[] = new Color[]{Color.RED, Color.BLUE, Color.GREEN}; 191 192 public ViewPort() { 193 setWidth100(); 194 setHeight100(); 195 setBorder("2px solid black"); 196 } 197 198 private void drawGrid(int N, int M) { 199 if (canvas == null) { 200 canvas = new GWTCanvas(getWidth(), getHeight()); 201 addMember(canvas); 202 } else { 203 canvas.clear(); 204 } 205 206 //draw horizontal lines 207 208 X = canvas.getCoordWidth(); 209 Y = canvas.getCoordHeight(); 210 211 double dx = X / N; 212 double dy = Y / M; 213 214 canvas.beginPath(); 215 216 canvas.setLineWidth(1); 217 canvas.setStrokeStyle(Color.BLACK); 218 219 for (int i = 0; i < N; i++) { 220 double x = dx * (i + 1); 221 222 canvas.moveTo(x, 0); 223 canvas.lineTo(x, Y); 224 } 225 226 //draw vertical lines 227 int j = M -1; 228 for (int i = 0; i < M; i++) { 229 double y = Y - dy * (j--); 230 231 canvas.moveTo(0, y); 232 canvas.lineTo(X, y); 233 } 234 235 canvas.stroke(); 236 237 } 238 239 private void drawLine(double[] y, double min, double max, Color color) { 240 canvas.beginPath(); 241 242 canvas.setLineWidth(2); 243 canvas.setStrokeStyle(color); 244 245 double xScale = X / y.length; 246 double yScale = Y / (max - min); 247 248 249 for (int i = 0; i < y.length -1; i++) { 250 canvas.moveTo(i * xScale, Y - (y[i] - min) * yScale); 251 canvas.lineTo((i + 1)* xScale, Y - (y[i + 1] - min) * yScale); 252 } 253 254 canvas.stroke(); 255 } 256 257 private String[] yLabels(double[]... y) { 258 String[] labels = new String[Y_SCALE]; 259 260 double min = min(y); 261 double max = max(y); 262 263 double s = (max - min)/Y_SCALE; 264 for (int i = 0; i < Y_SCALE; i++) { 265 labels[i] = Format.toUSString((min + i * s), 2); 266 } 267 268 return labels; 269 } 270 271 public void drawChart(String[] xLabels, double[] x, double[]... y) { 272 String[] yLabels = yLabels(y); 273 274 yAxis.drawLabels(yLabels); 275 xAxis.drawLabels(xLabels); 276 277 double min = min(y); 278 double max = max(y); 279 280 drawGrid(xLabels.length, yLabels.length); 281 282 for (int i = 0; i < y.length; i++) { 283 drawLine(y[i], min, max, COLOR[i]); 284 } 285 } 286 287 private double min(double[]... x) { 288 double min = x[0][0]; 289 for (int j = 0; j < x.length; j++ ) { 290 for (int i = 0; i < x[j].length; i++) { 291 if (x[j][i] < min) min = x[j][i]; 292 } 293 } 294 return min; 295 } 296 297 private double max(double[]... x) { 298 double max = x[0][0]; 299 for (int j = 0; j < x.length; j++) { 300 for (int i = 0; i < x[j].length; i++) { 301 if (x[j][i] > max) max = x[j][i]; 302 } 303 } 304 return max; 305 } 306 307 } 308 309}