]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
2dd769dcd4e7e561d27c55bf9bdae0a02e5d7784
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.properties.widgets;\r
13 \r
14 import java.awt.BasicStroke;\r
15 import java.awt.Color;\r
16 import java.awt.GridLayout;\r
17 import java.awt.geom.Ellipse2D;\r
18 import java.io.StringReader;\r
19 import java.util.ArrayList;\r
20 import java.util.Iterator;\r
21 \r
22 import javax.swing.JComponent;\r
23 import javax.swing.JPanel;\r
24 \r
25 import org.eclipse.jface.layout.GridDataFactory;\r
26 import org.eclipse.jface.viewers.ISelection;\r
27 import org.eclipse.swt.SWT;\r
28 import org.eclipse.swt.widgets.Composite;\r
29 import org.jfree.chart.ChartFactory;\r
30 import org.jfree.chart.JFreeChart;\r
31 import org.jfree.chart.axis.ValueAxis;\r
32 import org.jfree.chart.plot.PlotOrientation;\r
33 import org.jfree.chart.plot.XYPlot;\r
34 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;\r
35 import org.jfree.data.general.SeriesChangeEvent;\r
36 import org.jfree.data.general.SeriesChangeListener;\r
37 import org.jfree.data.xy.XYDataItem;\r
38 import org.jfree.data.xy.XYDataset;\r
39 import org.jfree.data.xy.XYSeries;\r
40 import org.jfree.data.xy.XYSeriesCollection;\r
41 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
42 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
43 import org.simantics.db.ReadGraph;\r
44 import org.simantics.db.Resource;\r
45 import org.simantics.db.WriteGraph;\r
46 import org.simantics.db.common.request.WriteRequest;\r
47 import org.simantics.db.exception.DatabaseException;\r
48 import org.simantics.db.management.ISessionContext;\r
49 import org.simantics.db.procedure.Listener;\r
50 import org.simantics.db.request.Read;\r
51 import org.simantics.sysdyn.SysdynResource;\r
52 import org.simantics.sysdyn.tableParser.ParseException;\r
53 import org.simantics.sysdyn.tableParser.TableParser;\r
54 import org.simantics.sysdyn.tableParser.Token;\r
55 import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupChartPanel;\r
56 import org.simantics.ui.SimanticsUI;\r
57 import org.simantics.utils.ui.ISelectionUtils;\r
58 import org.simantics.utils.ui.SWTAWTComponent;\r
59 \r
60 public class ChartWidget implements Widget {\r
61 \r
62     JFreeChart chart;\r
63     LookupChartPanel chartPanel;\r
64     SWTAWTComponent swtawtcomponent;\r
65 \r
66     public ChartWidget(Composite parent, WidgetSupport support, int style) {\r
67         support.register(this);\r
68         chartPanel = new LookupChartPanel(createChart());\r
69         chartPanel.setMouseZoomable(true, false);\r
70         chartPanel.setDomainZoomable(false);\r
71         chartPanel.setRangeZoomable(false);\r
72 \r
73         swtawtcomponent = new SWTAWTComponent(parent, SWT.BORDER) {\r
74             @Override\r
75             protected JComponent createSwingComponent() {\r
76                 JPanel panel = new JPanel();\r
77                 panel.setLayout(new GridLayout(1, 1));\r
78                 panel.add(chartPanel);\r
79                 panel.doLayout();\r
80                 return panel;\r
81             }\r
82         };\r
83         GridDataFactory.fillDefaults().grab(true, true).applyTo(swtawtcomponent);\r
84         swtawtcomponent.populate();\r
85 \r
86     }\r
87 \r
88     @Override\r
89     public void setInput(ISessionContext context, Object input) {\r
90 \r
91         final Resource expression = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
92 \r
93         class Auxiliary {\r
94             Double minX, minY, maxX, maxY;\r
95             String table;\r
96         }\r
97 \r
98         try {\r
99             SimanticsUI.getSession().syncRequest(new Read<Auxiliary>() {\r
100 \r
101                 @Override\r
102                 public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
103                         SysdynResource sr = SysdynResource.getInstance(graph);\r
104                         if(!graph.isInstanceOf(expression, sr.WithLookupExpression))\r
105                                 return null;\r
106                         Auxiliary auxiliary = new Auxiliary();\r
107                     auxiliary.minX = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_minX);\r
108                     auxiliary.maxX = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_maxX);\r
109                     auxiliary.minY = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_minY);\r
110                     auxiliary.maxY = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_maxY);\r
111                     auxiliary.table = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_lookup);\r
112                     return auxiliary;\r
113                 }\r
114             }, new Listener<Auxiliary>() {\r
115 \r
116                 @Override\r
117                 public void exception(Throwable t) {\r
118                     t.printStackTrace();\r
119                 }\r
120 \r
121                 @Override\r
122                 public void execute(Auxiliary result) {\r
123                         if(result == null) return;\r
124                     XYDataset dataset = createDataset(result.table);\r
125                     chartPanel.resetChart(dataset);\r
126                     chartPanel.addSeriesChangeListener(new _SeriesChangeListener(expression));\r
127                     \r
128                     XYPlot plot = (XYPlot) chart.getPlot();\r
129                     ValueAxis rangeAxis = plot.getRangeAxis();\r
130                     rangeAxis.setAutoRange(false);\r
131                     if(result.minY == null) result.minY = rangeAxis.getLowerBound();\r
132                     if(result.maxY == null) result.maxY = rangeAxis.getUpperBound();\r
133                     rangeAxis.setRange(result.minY, result.maxY);\r
134                     ValueAxis domainAxis = plot.getDomainAxis();\r
135                     domainAxis.setAutoRange(false);\r
136                     if(result.minX == null) result.minX = domainAxis.getLowerBound();\r
137                     if(result.maxX == null) result.maxX = domainAxis.getUpperBound();\r
138                     domainAxis.setRange(result.minX, result.maxX);\r
139 \r
140                 }\r
141 \r
142                 @Override\r
143                 public boolean isDisposed() {\r
144                     return swtawtcomponent.isDisposed();\r
145                 }\r
146 \r
147             });\r
148         } catch (DatabaseException e) {\r
149             e.printStackTrace();\r
150         }\r
151     }\r
152 \r
153     private JFreeChart createChart() {\r
154         XYDataset dataset = createDataset(null);\r
155         chart = ChartFactory.createXYLineChart(null, null, null,\r
156                 dataset, PlotOrientation.VERTICAL, false, true, false);\r
157         XYPlot plot = (XYPlot) chart.getPlot();\r
158         XYLineAndShapeRenderer renderer\r
159         = (XYLineAndShapeRenderer) plot.getRenderer();\r
160         renderer.setBaseShapesVisible(true);\r
161         renderer.setDrawOutlines(true);\r
162         renderer.setUseFillPaint(true);\r
163         renderer.setBaseFillPaint(Color.white);\r
164         renderer.setSeriesStroke(0, new BasicStroke(3.0f));\r
165         renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0f));\r
166         renderer.setSeriesShape(0, new Ellipse2D.Double(-5.0, -5.0, 10.0, 10.0));\r
167         return chart;\r
168     }\r
169 \r
170     public XYDataset createDataset(String table) {\r
171         XYSeries series = new XYSeries("Series");\r
172         \r
173         if(table != null) {\r
174             TableParser parser = new TableParser(new StringReader(""));\r
175             parser.ReInit(new StringReader(table));\r
176             try {\r
177                 parser.table();\r
178                 ArrayList<Token> xTokens = parser.getXTokens();\r
179                 ArrayList<Token> yTokens = parser.getYTokens();\r
180                 for(int i = 0; i < xTokens.size(); i++) {\r
181                     series.add(\r
182                             Double.parseDouble(xTokens.get(i).image), \r
183                             Double.parseDouble(yTokens.get(i).image));\r
184                 }\r
185             } catch (ParseException e1) {\r
186             }\r
187         }\r
188         \r
189         XYSeriesCollection dataset = new XYSeriesCollection();\r
190         dataset.addSeries(series);\r
191         return dataset;\r
192     }\r
193 \r
194     public LookupChartPanel getChartPanel() {\r
195         return this.chartPanel;\r
196     }\r
197 \r
198     public JFreeChart getChart() {\r
199         return this.chart;\r
200     }\r
201 \r
202     private class _SeriesChangeListener implements SeriesChangeListener {\r
203 \r
204         Resource expression;\r
205         \r
206         public _SeriesChangeListener(Resource expression) {\r
207             this.expression = expression;\r
208         }\r
209         @Override\r
210         public void seriesChanged(SeriesChangeEvent event) {\r
211             if(chartPanel.isDragging()) return;\r
212 \r
213             StringBuilder b = new StringBuilder();\r
214             b.append("{");\r
215             XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
216             XYSeries series = collection.getSeries(0);\r
217             if(series.isEmpty())\r
218                 return;\r
219             Iterator<?> iterator = series.getItems().iterator();\r
220             while(iterator.hasNext()){\r
221                 XYDataItem item = (XYDataItem)iterator.next();\r
222                 b.append("{" + item.getX() + "," + item.getY() + "}");\r
223                 if(iterator.hasNext())\r
224                     b.append(",");\r
225             }\r
226             b.append("}");\r
227             final String table = b.toString();\r
228 \r
229             SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
230 \r
231                 @Override\r
232                 public void perform(WriteGraph graph) throws DatabaseException {\r
233                     SysdynResource sr = SysdynResource.getInstance(graph);\r
234                     graph.claimLiteral(expression, sr.WithLookupExpression_lookup, table);\r
235                 }\r
236             });\r
237 \r
238         }\r
239     }\r
240 }\r