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