1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.color.scheme.impl;
25
26 import java.awt.Color;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import org.dishevelled.color.scheme.ColorFactory;
32 import org.dishevelled.color.scheme.ColorScheme;
33
34
35
36
37
38
39 public final class ContinuousColorScheme
40 implements ColorScheme
41 {
42
43 private final String name;
44
45
46 private final List<Color> colors;
47
48
49 private final List<Double> anchors;
50
51
52 private final double minimumValue;
53
54
55 private final double maximumValue;
56
57
58 private final ColorFactory colorFactory;
59
60
61
62
63
64
65
66
67
68
69
70 public ContinuousColorScheme(final String name,
71 final List<Color> colors,
72 final double minimumValue,
73 final double maximumValue,
74 final ColorFactory colorFactory)
75 {
76 if (colors == null)
77 {
78 throw new IllegalArgumentException("colors must not be null");
79 }
80 if (colors.size() < 2)
81 {
82 throw new IllegalArgumentException("colors must contain at least two colors");
83 }
84 if (colorFactory == null)
85 {
86 throw new IllegalArgumentException("colorFactory must not be null");
87 }
88 this.name = name;
89 this.colors = new ArrayList<Color>(colors);
90 this.minimumValue = minimumValue;
91 this.maximumValue = maximumValue;
92 this.colorFactory = colorFactory;
93
94
95 anchors = new ArrayList<Double>(colors.size());
96 double anchorLength = (Math.abs(maximumValue - minimumValue) / (colors.size() - 1));
97 for (int i = 0; i < colors.size(); i++)
98 {
99 anchors.add(Double.valueOf(i * anchorLength));
100 }
101 }
102
103
104
105
106
107
108
109 public String getName()
110 {
111 return name;
112 }
113
114 @Override
115 public double getMinimumValue()
116 {
117 return minimumValue;
118 }
119
120 @Override
121 public void setMinimumValue(final double minimumValue)
122 {
123 throw new UnsupportedOperationException("setMinimumValue operation not supported by this color scheme");
124 }
125
126 @Override
127 public double getMaximumValue()
128 {
129 return maximumValue;
130 }
131
132 @Override
133 public void setMaximumValue(final double maximumValue)
134 {
135 throw new UnsupportedOperationException("setMaximumValue operation not supported by this color scheme");
136 }
137
138 @Override
139 public double getZeroValue()
140 {
141 return Double.NaN;
142 }
143
144 @Override
145 public void setZeroValue(final double zeroValue)
146 {
147 throw new UnsupportedOperationException("setZeroValue operation not supported by this color scheme");
148 }
149
150 @Override
151 public ColorFactory getColorFactory()
152 {
153 return colorFactory;
154 }
155
156 @Override
157 public void setColorFactory(final ColorFactory colorFactory)
158 {
159 throw new UnsupportedOperationException("setMaximumValue operation not supported by this color scheme");
160 }
161
162
163
164
165
166
167 private Color getMinimumColor()
168 {
169 return colors.get(0);
170 }
171
172
173
174
175
176
177 private double getMinimumAnchor()
178 {
179 return anchors.get(0);
180 }
181
182
183
184
185
186
187 private Color getMaximumColor()
188 {
189 return colors.get(colors.size() - 1);
190 }
191
192 @Override
193 public Color getColor(final double value)
194 {
195 if (value < getMinimumAnchor())
196 {
197 return getMinimumColor();
198 }
199 Color lowerColor = getMinimumColor();
200 double lowerAnchor = getMinimumAnchor();
201 for (int i = 0; i < anchors.size(); i++)
202 {
203 double upperAnchor = anchors.get(i);
204 if (value == upperAnchor)
205 {
206 return colors.get(i);
207 }
208 else if (value < upperAnchor)
209 {
210 Color upperColor = colors.get(i);
211 lowerAnchor = anchors.get(i - 1);
212 lowerColor = colors.get(i - 1);
213 int r = (int) interpolate(value, lowerAnchor, upperAnchor,
214 (double) lowerColor.getRed(), (double) upperColor.getRed());
215 int g = (int) interpolate(value, lowerAnchor, upperAnchor,
216 (double) lowerColor.getGreen(), (double) upperColor.getGreen());
217 int b = (int) interpolate(value, lowerAnchor, upperAnchor,
218 (double) lowerColor.getBlue(), (double) upperColor.getBlue());
219 int a = (int) interpolate(value, lowerAnchor, upperAnchor,
220 (double) lowerColor.getAlpha(), (double) upperColor.getAlpha());
221 return colorFactory.createColor(r, g, b, ((float) a) / 255.0f);
222 }
223 }
224 return getMaximumColor();
225 }
226
227
228
229
230
231
232
233
234
235
236
237 private static double interpolate(final double value,
238 final double sourceMinimum,
239 final double sourceMaximum,
240 final double targetMinimum,
241 final double targetMaximum)
242 {
243 return targetMinimum + (targetMaximum - targetMinimum)
244 * ((value - sourceMinimum) / (sourceMaximum - sourceMinimum));
245 }
246 }