Addign build file
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / io / HTMLExporter.java
1 package com.billkuker.rocketry.motorsim.io;\r
2 \r
3 import java.io.OutputStream;\r
4 import java.io.PrintWriter;\r
5 import java.lang.reflect.InvocationTargetException;\r
6 import java.lang.reflect.Method;\r
7 import java.net.URLEncoder;\r
8 import java.text.DecimalFormat;\r
9 import java.text.NumberFormat;\r
10 import java.util.Iterator;\r
11 \r
12 import javax.measure.quantity.Duration;\r
13 import javax.measure.quantity.Force;\r
14 import javax.measure.quantity.Quantity;\r
15 import javax.measure.unit.SI;\r
16 import javax.measure.unit.Unit;\r
17 \r
18 import org.jscience.physics.amount.Amount;\r
19 \r
20 import com.billkuker.rocketry.motorsim.Burn;\r
21 import com.billkuker.rocketry.motorsim.BurnSummary;\r
22 import com.billkuker.rocketry.motorsim.GraphSimplifier;\r
23 import com.billkuker.rocketry.motorsim.RocketScience;\r
24 \r
25 public class HTMLExporter {\r
26 \r
27         @SuppressWarnings("deprecation")\r
28         private static String encode(String s) {\r
29                 return URLEncoder.encode(s).replace("%B2", "%C2%B2");\r
30         }\r
31 \r
32         private static <X extends Quantity, Y extends Quantity> String toChart(\r
33                         final Unit<X> xUnit, final Unit<Y> yUnit, final Object source,\r
34                         final String method, final Iterator<Amount<X>> domain, String title)\r
35                         throws SecurityException, NoSuchMethodException,\r
36                         IllegalArgumentException, IllegalAccessException,\r
37                         InvocationTargetException {\r
38                 NumberFormat nf = new DecimalFormat("#.##");\r
39                 Method f = source.getClass().getMethod(method, Amount.class);\r
40 \r
41                 double xMin = 0, xMax = 0;\r
42                 double yMin = 0, yMax = 0;\r
43 \r
44                 StringBuffer xVals = new StringBuffer();\r
45                 StringBuffer yVals = new StringBuffer();\r
46 \r
47                 while (domain.hasNext()) {\r
48                         Amount<X> aX = domain.next();\r
49                         double x = aX.doubleValue(xUnit);\r
50                         @SuppressWarnings("unchecked")\r
51                         double y = ((Amount<Y>) f.invoke(source, aX)).doubleValue(yUnit);\r
52                         xMin = x < xMin ? x : xMin;\r
53                         xMax = x > xMax ? x : xMax;\r
54                         yMin = y < yMin ? y : yMin;\r
55                         yMax = y > yMax ? y : yMax;\r
56 \r
57                         xVals.append(nf.format(x));\r
58                         xVals.append(",");\r
59                         yVals.append(nf.format(y));\r
60                         yVals.append(",");\r
61                 }\r
62                 xVals.deleteCharAt(xVals.length() - 1);\r
63                 yVals.deleteCharAt(yVals.length() - 1);\r
64 \r
65                 // Get the non-preferred Y Unit\r
66                 Unit<Y> yUnit2 = RocketScience.UnitPreference.SI\r
67                                 .getPreferredUnit(yUnit);\r
68                 // if ( yUnit2.equals(yUnit) )\r
69                 yUnit2 = RocketScience.UnitPreference.NONSI.getPreferredUnit(yUnit);\r
70                 double y2Min, y2Max;\r
71                 y2Min = Amount.valueOf(yMin, yUnit).doubleValue(yUnit2);\r
72                 y2Max = Amount.valueOf(yMax, yUnit).doubleValue(yUnit2);\r
73 \r
74                 // Get the non-preferred X Unit\r
75                 Unit<X> xUnit2 = RocketScience.UnitPreference.SI\r
76                                 .getPreferredUnit(xUnit);\r
77                 // if ( xUnit2.equals(xUnit) )\r
78                 xUnit2 = RocketScience.UnitPreference.NONSI.getPreferredUnit(xUnit);\r
79                 double x2Min, x2Max;\r
80                 x2Min = Amount.valueOf(xMin, xUnit).doubleValue(xUnit2);\r
81                 x2Max = Amount.valueOf(xMax, xUnit).doubleValue(xUnit2);\r
82 \r
83                 boolean x2 = !xUnit.equals(xUnit2);\r
84                 boolean y2 = x2 || !yUnit.equals(yUnit2);\r
85 \r
86                 StringBuffer sb = new StringBuffer();\r
87                 sb.append("<img src='");\r
88                 sb.append("http://chart.apis.google.com/chart?chxt=x,x,y,y"\r
89                                 + (y2 ? ",r,r" : "") + (x2 ? ",t,t" : "")\r
90                                 + "&chs=640x240&cht=lxy&chco=3072F3");\r
91                 sb.append("&chds=" + nf.format(xMin) + "," + nf.format(xMax) + ","\r
92                                 + nf.format(yMin) + "," + nf.format(yMax));\r
93                 sb.append("&chxr=" + "0," + nf.format(xMin) + "," + nf.format(xMax)\r
94                                 + "|2," + nf.format(yMin) + "," + nf.format(yMax));\r
95                 if (y2)\r
96                         sb.append("|4," + nf.format(y2Min) + "," + nf.format(y2Max));\r
97                 if (x2)\r
98                         sb.append("|6," + nf.format(x2Min) + "," + nf.format(x2Max));\r
99                 sb.append("&chd=t:" + xVals.toString() + "|" + yVals.toString());\r
100                 sb.append("&chxl=1:|" + encode(xUnit.toString()) + "|3:|"\r
101                                 + encode(yUnit.toString()));\r
102                 if (y2)\r
103                         sb.append("|5:|" + encode(yUnit2.toString()));\r
104                 if (x2)\r
105                         sb.append("|7:|" + encode(xUnit2.toString()));\r
106                 sb.append("&chxp=1,50|3,50");\r
107                 if (y2)\r
108                         sb.append("|5,50");\r
109                 if (x2)\r
110                         sb.append("|7,50");\r
111                 sb.append("&chtt=" + title);\r
112                 sb.append("' width='640' height='240' alt='" + title + "' />");\r
113 \r
114                 return sb.toString();\r
115         }\r
116 \r
117         public static void export(Burn b, OutputStream os) throws Exception {\r
118                 PrintWriter out = new PrintWriter(os);\r
119 \r
120                 BurnSummary bs = new BurnSummary(b);\r
121                 \r
122                 out.println("<!--Begin motor " + b.getMotor().getName() + " HTML export from MotorSim-->");\r
123                 out.print("<table class='motor'>");\r
124 \r
125                 out.print("<tr>");\r
126                 out.print("<th colspan='6' class='title'>" + b.getMotor().getName() + "</th>");\r
127                 out.print("</tr>");\r
128 \r
129                 out.print("<tr class='summary'>");\r
130                 out.print("<th>Rating:</th>");\r
131                 \r
132                 out.print("<td>" + bs.getRating() + "</td>");\r
133                 out.print("<th>Total Impulse:</th>");\r
134         \r
135                 out.print("<td>"\r
136                                 + RocketScience.ammountToRoundedString(bs.totalImpulse())\r
137                                 + "</td>");\r
138                 out.print("<th>Specific Impulse:</th>");\r
139                 out.print("<td>"\r
140                                 + RocketScience.ammountToRoundedString(bs.specificImpulse())\r
141                                 + "</td>");\r
142                 out.print("</tr>");\r
143                 \r
144                 \r
145                 out.print("<tr class='summary'>");\r
146                 out.print("<th>Max Thrust:</th>");\r
147                 \r
148                 \r
149                 out.print("<td>"\r
150                                 + RocketScience.ammountToRoundedString(bs.maxThrust())\r
151                                 + "</td>");\r
152                 out.print("<th>Average Thrust:</th>");\r
153         \r
154                 out.print("<td>"\r
155                                 + RocketScience.ammountToRoundedString(bs.averageThrust())\r
156                                 + "</td>");\r
157                 out.print("<th>Max Pressure:</th>");\r
158                 out.print("<td>"\r
159                                 + RocketScience.ammountToRoundedString(bs.maxPressure())\r
160                                 + "</td>");\r
161                 out.print("</tr>");\r
162 \r
163                 out.print("<tr>");\r
164                 out.print("<td colspan='6' class='thrust'>");\r
165                 GraphSimplifier<Duration, Force> thrust = new GraphSimplifier<Duration, Force>(\r
166                                 b, "thrust", b.getData().keySet().iterator());\r
167 \r
168                 out.print(toChart(SI.SECOND, SI.NEWTON, thrust, "value", thrust\r
169                                 .getDomain().iterator(), "Thrust"));\r
170                 out.print("</td>");\r
171                 /*\r
172                 out.print("<td colspan='3' class='pressure'>");\r
173                 GraphSimplifier<Duration, Pressure> pressure = new GraphSimplifier<Duration, Pressure>(\r
174                                 b, "pressure", b.getData().keySet().iterator());\r
175 \r
176                 out.print(toChart(SI.SECOND,\r
177                                 javax.measure.unit.SI.MEGA(javax.measure.unit.SI.PASCAL),\r
178                                 pressure, "value", pressure.getDomain().iterator(), "Pressure"));\r
179 \r
180                 out.print("</td>");\r
181                 */\r
182                 out.print("</tr>");\r
183                 /*\r
184                 out.print("<tr>");\r
185                 out.print("<th colspan='3'>.ENG File</th>");\r
186                 out.print("<th colspan='3'>MotorSim File</th>");\r
187                 out.print("</tr>");\r
188                 out.print("<tr>");\r
189                 out.print("<td colspan='3'>");\r
190                 out.print("<textarea>");\r
191                 out.flush();\r
192                 os.flush();\r
193                 ENGExporter.export(b, os);\r
194                 os.flush();\r
195                 out.print("</textarea>");\r
196                 out.print("</td>");\r
197                 out.print("<td colspan='3'>");\r
198                 out.print("<textarea>");\r
199                 out.print(MotorIO.writeMotor(b.getMotor()).replace("<", "&lt;").replace(">", "&gt;"));\r
200                 out.print("</textarea>");\r
201                 out.print("</td>");\r
202                 out.print("</tr>");\r
203                 */\r
204                 out.print("</table>");\r
205 \r
206                 out.println("\n<!--End motor " + b.getMotor().getName() + "-->");\r
207                 out.flush();\r
208                 out.close();\r
209         }\r
210 \r
211 }\r