]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
44db3f032593f203967debfc278860fdcffbdc85
[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.expressions;\r
13 \r
14 import java.awt.Point;\r
15 import java.awt.event.MouseEvent;\r
16 import java.awt.geom.Point2D;\r
17 import java.awt.geom.Rectangle2D;\r
18 \r
19 import org.jfree.chart.ChartPanel;\r
20 import org.jfree.chart.ChartRenderingInfo;\r
21 import org.jfree.chart.JFreeChart;\r
22 import org.jfree.chart.axis.ValueAxis;\r
23 import org.jfree.chart.entity.ChartEntity;\r
24 import org.jfree.chart.entity.PlotEntity;\r
25 import org.jfree.chart.entity.XYItemEntity;\r
26 import org.jfree.chart.plot.XYPlot;\r
27 import org.jfree.data.general.SeriesChangeListener;\r
28 import org.jfree.data.xy.XYDataset;\r
29 import org.jfree.data.xy.XYSeries;\r
30 import org.jfree.data.xy.XYSeriesCollection;\r
31 \r
32 @SuppressWarnings("serial")\r
33 public class LookupChartPanel extends ChartPanel {\r
34 \r
35     private XYItemEntity dragPrevEntity;\r
36     private boolean drawing;\r
37     private XYSeries series; \r
38     private JFreeChart chart;\r
39     private SeriesChangeListener changeListener;\r
40 \r
41     public LookupChartPanel(JFreeChart chart) {\r
42         super(chart);\r
43         this.chart = chart;\r
44         XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
45         series = collection.getSeries(0); \r
46     }\r
47 \r
48     public void mouseDragged(MouseEvent e)\r
49     {\r
50         if(dragPrevEntity != null) {\r
51 \r
52             int item = dragPrevEntity.getItem();\r
53             XYPlot plot = (XYPlot)chart.getPlot();\r
54             ValueAxis rangeAxis = plot.getRangeAxis();\r
55             ValueAxis domainAxis = plot.getDomainAxis();\r
56             Point2D location = getLocationOnChart(getMouseLocation(e));\r
57             Number prevX = item == 0 ? null : series.getX(item - 1);\r
58             Number nextX = item == series.getItemCount() - 1 ? null : series.getX(item + 1);\r
59 \r
60 \r
61             if(series.indexOf(location.getX()) >= 0 && series.indexOf(location.getX()) != item)\r
62                 return;\r
63             else if (prevX != null && location.getX() < prevX.doubleValue())\r
64                 location.setLocation(series.getX(item).doubleValue(), location.getY());\r
65             else if (nextX != null && location.getX() > nextX.doubleValue())\r
66                 location.setLocation(series.getX(item).doubleValue(), location.getY());\r
67             else if (location.getX() > domainAxis.getUpperBound())\r
68                 location.setLocation(domainAxis.getUpperBound(), location.getY());\r
69             else if (location.getX() < domainAxis.getLowerBound()) \r
70                 location.setLocation(domainAxis.getLowerBound(), location.getY());    \r
71 \r
72             if (location.getY() > rangeAxis.getUpperBound())\r
73                 location.setLocation(location.getX(), rangeAxis.getUpperBound());\r
74             else if (location.getY() < rangeAxis.getLowerBound()) \r
75                 location.setLocation(location.getX(), rangeAxis.getLowerBound());    \r
76 \r
77             removeItemFromSeries(dragPrevEntity.getItem());\r
78             addLocationToSeries(location);\r
79         } else {\r
80             ChartEntity currEntity = this.getEntityForPoint(e.getX(),e.getY());\r
81             if(!drawing && currEntity instanceof XYItemEntity) {\r
82                 dragPrevEntity = ((XYItemEntity)currEntity);\r
83             } else if (currEntity instanceof PlotEntity){\r
84                 drawing = true;\r
85                 Point2D locationOnChart = getLocationOnChart(getMouseLocation(e));\r
86                 int item = series.indexOf(locationOnChart.getX());\r
87                 if (item >= 0) {\r
88                     Point2D location = new Point2D.Double(series.getX(item).doubleValue(), series.getY(item).doubleValue());\r
89                     Point2D javaLocation = getLocationOnJava2D(location);\r
90                     removeItemFromSeries(item);\r
91                     addLocationToSeries(getLocationOnChart(new Point2D.Double(javaLocation.getX(), e.getY())));\r
92                 }\r
93             }\r
94         }\r
95 \r
96     }\r
97 \r
98     public void mouseReleased(MouseEvent e) {\r
99         if(isDragging()) {\r
100             dragPrevEntity = null;\r
101             if(changeListener != null)\r
102                 changeListener.seriesChanged(null);\r
103         }\r
104         drawing = false;\r
105 \r
106     }\r
107 \r
108     public void mouseClicked(MouseEvent e)\r
109     {\r
110         if(e.getButton() == MouseEvent.BUTTON1) {\r
111             addLocationToSeries(getLocationOnChart(getMouseLocation(e)));\r
112         } else if (e.getButton() == MouseEvent.BUTTON3) {\r
113             ChartEntity entity = this.getEntityForPoint(e.getX(),e.getY());\r
114             if(entity instanceof XYItemEntity) {\r
115                 XYItemEntity xyentity = ((XYItemEntity)entity);\r
116                 removeItemFromSeries(xyentity.getItem());\r
117             }\r
118         }\r
119     }         \r
120 \r
121     private Point2D getLocationOnChart(Point2D coordinates) {\r
122         XYPlot plot = (XYPlot)chart.getPlot();\r
123         ChartRenderingInfo info = getChartRenderingInfo();\r
124         Rectangle2D dataArea = info.getPlotInfo().getDataArea();\r
125         double chartX = plot.getDomainAxis().java2DToValue(coordinates.getX(), dataArea,\r
126                 plot.getDomainAxisEdge());\r
127         double chartY = plot.getRangeAxis().java2DToValue(coordinates.getY(), dataArea,\r
128                 plot.getRangeAxisEdge());\r
129         return new Point2D.Double(chartX, chartY);\r
130     }\r
131 \r
132     private Point2D getLocationOnJava2D(Point2D location) {\r
133         XYPlot plot = (XYPlot)chart.getPlot();\r
134         ChartRenderingInfo info = getChartRenderingInfo();\r
135         Rectangle2D dataArea = info.getPlotInfo().getDataArea();\r
136         double javaX = plot.getDomainAxis().valueToJava2D(location.getX(), dataArea,\r
137                 plot.getDomainAxisEdge());\r
138         double javaY = plot.getRangeAxis().valueToJava2D(location.getY(), dataArea,\r
139                 plot.getRangeAxisEdge());\r
140         return new Point2D.Double(javaX, javaY);\r
141     }\r
142 \r
143     public void addLocationToSeries(Point2D location) {\r
144         if(series.indexOf(location.getX()) < 0) {\r
145             series.add(location.getX(), location.getY());\r
146         }\r
147     }\r
148 \r
149     public void removeItemFromSeries(int item){\r
150         series.remove(item);\r
151     }\r
152     \r
153     public void resetChart(XYDataset dataset) {\r
154         XYPlot plot = (XYPlot)chart.getPlot();\r
155         plot.setDataset(dataset);\r
156         XYSeriesCollection collection = (XYSeriesCollection) plot.getDataset();\r
157         series = collection.getSeries(0); \r
158     }\r
159 \r
160     private Point2D getMouseLocation(MouseEvent e) {\r
161         int mouseX = e.getX();\r
162         int mouseY = e.getY();\r
163         Point2D p = translateScreenToJava2D(\r
164                 new Point(mouseX, mouseY));\r
165         return p;\r
166     }\r
167 \r
168     public void addSeriesChangeListener(SeriesChangeListener listener) {\r
169         this.changeListener = listener;\r
170         this.series.addChangeListener(changeListener);\r
171     }\r
172 \r
173     public boolean isDragging() {\r
174         return dragPrevEntity != null;\r
175     }\r
176 }\r