]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph.swing/src/org/simantics/scenegraph/swing/MultiVariableTrendNode.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scenegraph.swing / src / org / simantics / scenegraph / swing / MultiVariableTrendNode.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.scenegraph.swing;
13
14 import java.awt.Graphics2D;\r
15 import java.awt.geom.AffineTransform;\r
16 import java.util.ArrayList;\r
17 import java.util.List;\r
18 \r
19 import javax.swing.JPanel;\r
20 \r
21 import org.jfree.chart.ChartFactory;\r
22 import org.jfree.chart.ChartPanel;\r
23 import org.jfree.chart.JFreeChart;\r
24 import org.jfree.chart.axis.ValueAxis;\r
25 import org.jfree.chart.plot.PlotOrientation;\r
26 import org.jfree.chart.plot.XYPlot;\r
27 import org.jfree.data.xy.XYSeries;\r
28 import org.jfree.data.xy.XYSeriesCollection;\r
29 import org.simantics.scenegraph.ExportableWidget.RasterOutputWidget;\r
30 import org.simantics.scenegraph.g2d.nodes.Trend2DNode.TrendPoint;\r
31 \r
32 @RasterOutputWidget
33 public class MultiVariableTrendNode extends ComponentNode<JPanel> {
34
35     /**
36      * 
37      */
38     private static final long serialVersionUID = 8508750881358776559L;
39     \r
40     protected transient JFreeChart chart = null;
41     protected transient List<List<TrendPoint>> points = new ArrayList<List<TrendPoint>>();
42     protected transient XYSeriesCollection dataset = null;\r
43     
44     @Override\r
45     public void init() {\r
46         XYSeries serie = new XYSeries("Trend");\r
47         dataset = new XYSeriesCollection(serie);\r
48         scale = false;\r
49 \r
50         chart = ChartFactory.createXYLineChart(\r
51                         "Trend", // Title\r
52                         "Value", // X-title\r
53                         "Time",  // Y-title\r
54                 dataset,\r
55                 PlotOrientation.VERTICAL,\r
56                 false,\r
57                 true,\r
58                 false\r
59         );\r
60         final XYPlot plot = chart.getXYPlot();\r
61         ValueAxis axis = plot.getDomainAxis();\r
62         axis.setAutoRange(true);\r
63 //        axis.setFixedAutoRange(60000.0);  // 60 seconds\r
64 \r
65         component = new ChartPanel(chart, false);\r
66         ((ChartPanel)component).setRefreshBuffer(false);\r
67         component.setIgnoreRepaint(true); \r
68         component.setDoubleBuffered(false);\r
69         if(bounds != null) {\r
70             component.setBounds(0, 0, 0, 0);\r
71         }\r
72 \r
73         for(int i = 0; i < points.size(); i++) {\r
74                 if(dataset.getSeriesCount() < i) {\r
75                         XYSeries s = new XYSeries("Serie "+(i+1));\r
76                         dataset.addSeries(s);\r
77                         dataset.addSeries(s);\r
78                 }\r
79             for(TrendPoint p : points.get(i)) {\r
80                 try {\r
81                         dataset.getSeries(i).add(p.getX(), p.getY());\r
82                 } catch(org.jfree.data.general.SeriesException e) {\r
83 \r
84                 }\r
85             }\r
86         }\r
87         super.init();\r
88     }\r
89
90     @Override
91     public void render(Graphics2D g2d) {
92         if (component != null) {\r
93                 AffineTransform ot = g2d.getTransform();\r
94             g2d.transform(transform);\r
95             double scaleX = g2d.getTransform().getScaleX();
96             double scaleY = g2d.getTransform().getScaleY();
97 \r
98             AffineTransform at = new AffineTransform();
99             at.setToTranslation(bounds.getMinX(), bounds.getMinY());
100             at.scale(1/scaleX, 1/scaleY);
101             g2d.transform(at);
102             int width = (int)(bounds.getWidth() * scaleX);
103             int height = (int)(bounds.getHeight() * scaleY);
104
105                 synchronized(component) {\r
106                     component.setLocation((int)g2d.getTransform().getTranslateX(), (int)g2d.getTransform().getTranslateY());\r
107                     if(component.getSize().getWidth() != width || component.getSize().getHeight() != height) {
108                         component.setSize(width, height);\r
109                     }
110                     component.paint(g2d);\r
111                 }\r
112                 g2d.setTransform(ot);
113         }
114     }\r
115     \r
116     @PropertySetter("Title")
117     @ClientSide
118     public void setTitle(String title) {
119         if(component != null) {
120                 synchronized(component) {\r
121                         ((ChartPanel)component).getChart().setTitle(title);\r
122                 }\r
123         }
124     }
125 \r
126     @PropertySetter("X-Axis Label")
127     @ClientSide\r
128     public void setXTitle(String xTitle) {
129         if(component != null) {\r
130                 synchronized(component) {\r
131                         ((ChartPanel)component).getChart().getXYPlot().getDomainAxis().setLabel(xTitle);\r
132                 }\r
133         }\r
134     }
135 \r
136     @PropertySetter("Y-Axis Label")
137     @ClientSide\r
138     public void setYTitle(String yTitle) {
139         if(component != null) {\r
140                 synchronized(component) {\r
141                         ((ChartPanel)component).getChart().getXYPlot().getRangeAxis().setLabel(yTitle);\r
142                 }\r
143         }\r
144     }\r
145     
146     @ClientSide\r
147     public void setPoints(List<TrendPoint> points, Integer serie) {\r
148         while(dataset.getSeriesCount() <= serie) {\r
149                 this.points.add(new ArrayList<TrendPoint>());\r
150                 dataset.addSeries(new XYSeries("Trend "+(dataset.getSeriesCount()+1)));\r
151         }
152         this.points.add(serie, points);
153         synchronized(component) {\r
154                 dataset.getSeries(serie.intValue()).clear();
155                 for(TrendPoint p : points) {
156                     try {
157                         dataset.getSeries(serie.intValue()).add(p.getX(), p.getY());
158                     } catch(org.jfree.data.general.SeriesException e) {
159         
160                     }
161                 }\r
162         }
163     }
164
165     @ClientSide
166     protected void appendPoints(List<TrendPoint> points, Integer serie) {
167         while(dataset.getSeriesCount() <= serie) {\r
168                 this.points.add(new ArrayList<TrendPoint>());\r
169                 dataset.addSeries(new XYSeries("Trend "+(dataset.getSeriesCount()+1)));\r
170         }        \r
171         /**
172          * We need to have the same set of points on the both sides, so locally the points are just updated,
173          * but on remote side we send only the new points.
174          * In case we are running on local workbench, the point list is updated and in addition these points
175          * would be added to the list without this check.
176          * FIXME: find out some way to implement this without this check
177          */
178         if(location.equals(Location.REMOTE)) {
179             this.points.get(serie).addAll(points);
180         }
181
182         for(TrendPoint p : points) {
183             try {
184                 dataset.getSeries(serie).add(p.getX(), p.getY());
185             } catch(org.jfree.data.general.SeriesException e) {
186
187             }
188         }
189     }
190 }