1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.properties.widgets.expressions;
\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
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
32 @SuppressWarnings("serial")
\r
33 public class LookupChartPanel extends ChartPanel {
\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
41 public LookupChartPanel(JFreeChart chart) {
\r
44 XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();
\r
45 series = collection.getSeries(0);
\r
48 public void mouseDragged(MouseEvent e)
\r
50 if(dragPrevEntity != null) {
\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
61 if(series.indexOf(location.getX()) >= 0 && series.indexOf(location.getX()) != item)
\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
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
77 removeItemFromSeries(dragPrevEntity.getItem());
\r
78 addLocationToSeries(location);
\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
85 Point2D locationOnChart = getLocationOnChart(getMouseLocation(e));
\r
86 int item = series.indexOf(locationOnChart.getX());
\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
98 public void mouseReleased(MouseEvent e) {
\r
100 dragPrevEntity = null;
\r
101 if(changeListener != null)
\r
102 changeListener.seriesChanged(null);
\r
108 public void mouseClicked(MouseEvent e)
\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
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
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
143 public void addLocationToSeries(Point2D location) {
\r
144 if(series.indexOf(location.getX()) < 0) {
\r
145 series.add(location.getX(), location.getY());
\r
149 public void removeItemFromSeries(int item){
\r
150 series.remove(item);
\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
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
168 public void addSeriesChangeListener(SeriesChangeListener listener) {
\r
169 this.changeListener = listener;
\r
170 this.series.addChangeListener(changeListener);
\r
173 public boolean isDragging() {
\r
174 return dragPrevEntity != null;
\r