View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans.
5    *
6    * CosyBeans is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.adapters;
21  
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import com.cosylab.gui.displayers.CommonDisplayer;
26  import com.cosylab.gui.displayers.DoubleConsumer;
27  
28  
29  /**
30   * <code>MulitplierConverter</code> acts as data source and data consumer in
31   * the same time. This converter performas on all data flow  linear
32   * transformation with user defined multiplication factor and shift. Value
33   * transfirmation performs <code>x  multiplicationFactor + shift</code>.
34   * 
35   * <p>
36   * <b>Note!</b> This implementation works only with data sources and consumers,
37   * whcih support <code>double</code> as value type.
38   * </p>
39   *
40   * @author <a href="mailto:igor.kriznar@cosylab.com">Igor Kriznar</a>
41   * @version $Id: LinearConverter.java,v 1.16 2008-04-22 12:31:02 jbobnar Exp $
42   *
43   * @see com.cosylab.gui.adapters.Converter
44   * @see com.cosylab.gui.adapters.SimpleConverterSupport
45   * @since Feb 14, 2004.
46   */
47  @SuppressWarnings("unchecked")
48  public class LinearConverter extends SimpleConverterSupport implements DoubleConsumer
49  {
50  
51  	private static final long serialVersionUID = -9041321592219301979L;
52  
53  	public static final String SHORT_NAME = "Linear";
54  	
55  	// the multiplication factor
56  	private double multiplicationFactor = 1.0;
57  
58  	// the the shift
59  	private double shift = 0.0;
60  
61  	/**
62  	 * Creates new multiplyer with default factor 1.0 and shift 0.0.
63  	 */
64  	public LinearConverter()
65  	{
66  		this(1.0, 0.0);
67  	}
68  
69  	/**
70  	 * Creates new multiplyer with defined factor and shift.
71  	 *
72  	 * @param factor new multiplicationfactor
73  	 * @param shift new shift
74  	 */
75  	public LinearConverter(double factor, double shift)
76  	{
77  		// default value
78  		setMultiplicationFactor(factor);
79  		setShift(shift);
80  
81  		// the name of this converter when it acts as a consumer
82  		name = "LinearConverter";
83  	}
84  
85  	/**
86  	 * This is called by peer data source. Call is delegated to contained
87  	 * consumers. In the process it is modified with multiplication factor
88  	 *
89  	 * @see com.cosylab.gui.displayers.DataConsumer#setCharacteristics(java.util.Map)
90  	 */
91  	public void setCharacteristics(Map characteristics)
92  	{
93  		// we store unmodified characteristic for possible later reinitialization of 
94  		// consumers, eg. if multiplication factor changes
95  		cacheLastCharacteristics(characteristics);
96  
97  		HashMap map = new HashMap(characteristics);
98  
99  		double min;
100 		double max;
101 
102 		if (map.containsKey(CommonDisplayer.C_GRAPH_MIN)
103 		    && map.containsKey(CommonDisplayer.C_GRAPH_MAX)) {
104 			min = ((Number)map.get(CommonDisplayer.C_GRAPH_MIN)).doubleValue();
105 			max = ((Number)map.get(CommonDisplayer.C_GRAPH_MAX)).doubleValue();
106 			
107 			if (multiplicationFactor < 0) {
108 				double a = max;
109 				max = min;
110 				min = a;
111 			}
112 			
113 			map.put(CommonDisplayer.C_GRAPH_MIN, new Double(transform(min)));
114 			map.put(CommonDisplayer.C_GRAPH_MAX, new Double(transform(max)));
115 		}
116 
117 		if (map.containsKey(CommonDisplayer.C_MINIMUM)
118 		    && map.containsKey(CommonDisplayer.C_MAXIMUM)) {
119 			min = ((Number)map.get(CommonDisplayer.C_MINIMUM)).doubleValue();
120 			max = ((Number)map.get(CommonDisplayer.C_MAXIMUM)).doubleValue();
121 
122 			if (multiplicationFactor < 0) {
123 				double a = max;
124 				max = min;
125 				min = a;
126 			}
127 			
128 			map.put(CommonDisplayer.C_MINIMUM, new Double(transform(min)));
129 			map.put(CommonDisplayer.C_MAXIMUM, new Double(transform(max)));
130 		}
131 
132 		map.put(CommonDisplayer.C_UNITS,
133 			    "1/" + multiplicationFactor + "*" + map.get(CommonDisplayer.C_UNITS));
134 
135 		super.setCharacteristics(map);
136 	}
137 
138 	/**
139 	 * Returns factor by which all data from input will be multiplied
140 	 *
141 	 * @return multiplication factor
142 	 */
143 	public double getMultiplicationFactor()
144 	{
145 		return multiplicationFactor;
146 	}
147 
148 	/**
149 	 * Sets factor by which all data from input will be multiplied
150 	 *
151 	 * @param d new multiplication factor
152 	 */
153 	public void setMultiplicationFactor(double d)
154 	{
155 		multiplicationFactor = d;
156 
157 		if (getLastCharacteristics() != null) {
158 			// reinitialize the peer consumers with changed multiplication factor
159 			setCharacteristics(getLastCharacteristics());
160 		}
161 	}
162 
163 	/**
164 	 * Here we implement our transformation function.
165 	 *
166 	 * @see com.cosylab.gui.adapters.SimpleConverterSupport#transform(double)
167 	 */
168 	protected double transform(double value)
169 	{
170 		return value * multiplicationFactor + shift;
171 	}
172 
173 	/**
174 	 * Here we implement invers transformation of our transformation function.
175 	 *
176 	 * @see com.cosylab.gui.adapters.SimpleConverterSupport#inverseTransform(double)
177 	 */
178 	protected double inverseTransform(double value)
179 	{
180 		return (value - shift) / multiplicationFactor;
181 	}
182 
183 	/**
184 	 * Returns the shift of transformed value.
185 	 *
186 	 * @return the shift of transformed value
187 	 */
188 	public double getShift()
189 	{
190 		return shift;
191 	}
192 
193 	/**
194 	 * Sets the shift of transformed value
195 	 *
196 	 * @param d new shift value
197 	 */
198 	public void setShift(double d)
199 	{
200 		shift = d;
201 
202 		if (getLastCharacteristics() != null) {
203 			// reinitialize the peer consumers with changed shift
204 			setCharacteristics(getLastCharacteristics());
205 		}
206 	}
207 	
208 	/*
209 	 * (non-Javadoc)
210 	 * @see com.cosylab.gui.adapters.DataConsumerDispatcher#getName()
211 	 */
212 	public String getName(){
213 		return SHORT_NAME;
214 	}
215 	
216 	/*
217 	 * (non-Javadoc)
218 	 * @see java.lang.Object#toString()
219 	 */
220 	public String toString(){
221 		return SHORT_NAME + ": " + getMultiplicationFactor() + ", " + getShift();
222 	}
223 	
224 	/*
225 	 * (non-Javadoc)
226 	 * @see java.lang.Object#equals(java.lang.Object)
227 	 */
228 	@Override
229 	public boolean equals(Object obj) {
230 		if (!(obj instanceof LinearConverter)) return false;
231 		LinearConverter c = (LinearConverter)obj;
232 		return c.getMultiplicationFactor() == multiplicationFactor && c.getShift() == shift;
233 	}
234 
235 }
236 
237 /* __oOo__ */