import java.awt.Color;\r
import java.awt.Font;\r
import java.awt.Stroke;\r
+import java.awt.Toolkit;\r
+import java.awt.datatransfer.StringSelection;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
import java.lang.reflect.InvocationTargetException;\r
import java.lang.reflect.Method;\r
import java.util.Collection;\r
import javax.measure.quantity.Area;\r
import javax.measure.quantity.Length;\r
import javax.measure.quantity.Quantity;\r
-import javax.measure.quantity.Volume;\r
import javax.measure.unit.SI;\r
import javax.measure.unit.Unit;\r
import javax.swing.JFrame;\r
+import javax.swing.JMenuItem;\r
import javax.swing.JPanel;\r
import javax.swing.SwingUtilities;\r
\r
private final Stroke dashed = new BasicStroke(1, 1, 1, 1, new float[]{2,4}, 0);\r
private final Font labelFont = new Font(Font.DIALOG, Font.BOLD, 10);\r
\r
- private static ThreadFactory tf = new ThreadFactory() {\r
+ private static ThreadFactory fastTF = new ThreadFactory() {\r
public Thread newThread(Runnable r) {\r
Thread t = new Thread(r);\r
t.setDaemon(true);\r
+ t.setName("Fast Chart Draw");\r
return t;\r
}\r
};\r
- private static ExecutorService fast = Executors.newFixedThreadPool(2, tf);\r
- private static ExecutorService slow = Executors.newFixedThreadPool(2, tf);\r
+ private static ThreadFactory slowTF = new ThreadFactory() {\r
+ public Thread newThread(Runnable r) {\r
+ Thread t = new Thread(r);\r
+ t.setDaemon(true);\r
+ t.setName("Slow Chart Draw");\r
+ return t;\r
+ }\r
+ };\r
+ private static ExecutorService fast = Executors.newFixedThreadPool(2, fastTF);\r
+ private static ExecutorService slow = Executors.newFixedThreadPool(2, slowTF);\r
\r
\r
public class IntervalDomain implements Iterable<Amount<X>> {\r
Unit<X> xUnit;\r
Unit<Y> yUnit;\r
\r
+ String xLabel;\r
+ String yLabel;\r
+ \r
Object source;\r
Method f;\r
\r
Iterable<Amount<X>> domain;\r
-\r
- public Chart(Unit<X> xUnit, Unit<Y> yUnit, Object source, String method)\r
+ \r
+ public Chart(Unit<X> xUnit, Unit<Y> yUnit, Object source, String method, String xLabel, String yLabel)\r
throws NoSuchMethodException {\r
super(new BorderLayout());\r
f = source.getClass().getMethod(method, Amount.class);\r
\r
this.xUnit = xUnit;\r
this.yUnit = yUnit;\r
+ \r
+ this.xLabel = xLabel;\r
+ this.yLabel = yLabel;\r
\r
RocketScience.addUnitPreferenceListener(this);\r
\r
setup();\r
}\r
\r
+ private static String toTitle(Method f) {\r
+ String ret = f.getName().substring(0, 1).toUpperCase()\r
+ + f.getName().substring(1);\r
+ ret = ret.replaceAll("(\\p{Ll})(\\p{Lu})", "$1 $2");\r
+ return ret;\r
+ }\r
+ \r
private void setup(){\r
removeAll();\r
this.xUnit = RocketScience.UnitPreference.getUnitPreference()\r
this.yUnit = RocketScience.UnitPreference.getUnitPreference()\r
.getPreferredUnit(yUnit);\r
\r
- chart = ChartFactory.createXYLineChart(f.getName().substring(0, 1)\r
- .toUpperCase()\r
- + f.getName().substring(1), // Title\r
- this.xUnit.toString(), // x-axis Label\r
- this.yUnit.toString(), // y-axis Label\r
+ chart = ChartFactory.createXYLineChart(\r
+ toTitle(f), // Title\r
+ xLabel + " (" + xUnit.toString() + ")", // x-axis Label\r
+ yLabel + " (" + yUnit.toString() + ")", // y-axis Label\r
dataset, PlotOrientation.VERTICAL, // Plot Orientation\r
false, // Show Legend\r
true, // Use tool tips\r
false // Configure chart to generate URLs?\r
);\r
- add(new ChartPanel(chart));\r
+ ChartPanel cp = new ChartPanel(chart);\r
+ cp.getPopupMenu().add(new JMenuItem("Copy CSV to Clipboard") {\r
+ private static final long serialVersionUID = 1L;\r
+ {\r
+ addActionListener(new ActionListener() {\r
+ @Override\r
+ public void actionPerformed(ActionEvent ae) {\r
+ XYSeries s = dataset.getSeries(0);\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(f.getName().substring(0, 1).toUpperCase()\r
+ + f.getName().substring(1));\r
+ sb.append("\n");\r
+ sb.append(Chart.this.chart.getXYPlot().getDomainAxis().getLabel());\r
+ sb.append(",");\r
+ sb.append(Chart.this.chart.getXYPlot().getRangeAxis().getLabel());\r
+ sb.append("\n");\r
+ for (int i = 0; i < s.getItemCount(); i++) {\r
+ sb.append(s.getX(i));\r
+ sb.append(",");\r
+ sb.append(s.getY(i));\r
+ sb.append("\n");\r
+ }\r
+ Toolkit.getDefaultToolkit()\r
+ .getSystemClipboard()\r
+ .setContents(\r
+ new StringSelection(sb.toString()),\r
+ null);\r
+ }\r
+ });\r
+ }\r
+ }, 3);\r
+ add(cp);\r
}\r
\r
\r
{\r
setContentPane(Chart.this);\r
setSize(640, 480);\r
- setDefaultCloseOperation(DISPOSE_ON_CLOSE);\r
+ setDefaultCloseOperation(EXIT_ON_CLOSE);\r
}\r
}.setVisible(true);\r
}\r
g.setID(Amount.valueOf(10, SI.MILLIMETER));\r
\r
Chart<Length, Area> c = new Chart<Length, Area>(SI.MILLIMETER,\r
- SI.MILLIMETER.pow(2).asType(Area.class), g, "surfaceArea");\r
+ SI.MILLIMETER.pow(2).asType(Area.class), g, "surfaceArea", "Regression", "Area");\r
\r
c.setDomain(c.new IntervalDomain(Amount.valueOf(0, SI.CENTIMETER), g\r
.webThickness()));\r
\r
c.show();\r
\r
+ /*\r
Chart<Length, Volume> v = new Chart<Length, Volume>(SI.MILLIMETER,\r
SI.MILLIMETER.pow(3).asType(Volume.class), g, "volume");\r
\r
v.setDomain(c.new IntervalDomain(Amount.valueOf(0, SI.CENTIMETER), g\r
.webThickness()));\r
\r
- v.show();\r
+ v.show();*/\r
}\r
\r
\r