View Javadoc
1   /*
2   
3       dsh-color-scheme  Color schemes.
4       Copyright (c) 2009-2016 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
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   * Discrete divergent color scheme.
36   *
37   * @author  Michael Heuer
38   */
39  public final class DiscreteDivergentColorScheme
40      implements ColorScheme
41  {
42      /** Name. */
43      private final String name;
44  
45      /** List of colors. */
46      private final List<Color> colors;
47  
48      /** List of anchors. */
49      private final List<Double> anchors;
50  
51      /** Minimum value. */
52      private double minimumValue;
53  
54      /** Maximum value. */
55      private double maximumValue;
56  
57      /** Zero value. */
58      private double zeroValue;
59  
60      /** Color factory. */
61      private final ColorFactory colorFactory;
62  
63  
64      /**
65       * Create a new discrete divergent color scheme.
66       *
67       * @param name name
68       * @param colors list of colors, must not be null and must contain at least two colors
69       * @param minimumValue minimum value
70       * @param zeroValue zero value
71       * @param maximumValue maximum value
72       * @param colorFactory color factory, must not be null
73       */
74      public DiscreteDivergentColorScheme(final String name,
75                                          final List<Color> colors,
76                                          final double minimumValue,
77                                          final double zeroValue,
78                                          final double maximumValue,
79                                          final ColorFactory colorFactory)
80      {
81          if (colors == null)
82          {
83              throw new IllegalArgumentException("colors must not be null");
84          }
85          if (colors.size() < 2)
86          {
87              throw new IllegalArgumentException("colors must contain at least two colors");
88          }
89          if (colorFactory == null)
90          {
91              throw new IllegalArgumentException("colorFactory must not be null");
92          }
93          this.name = name;
94          this.colors = new ArrayList<Color>(colors);
95          this.minimumValue = minimumValue;
96          this.zeroValue = zeroValue;
97          this.maximumValue = maximumValue;
98          this.colorFactory = colorFactory;
99  
100         anchors = new ArrayList<Double>(colors.size() - 1);
101         recalculateAnchors();
102     }
103 
104 
105     /**
106      * Recalculate anchors.
107      */
108     private void recalculateAnchors()
109     {
110         if (!anchors.isEmpty())
111         {
112             anchors.clear();
113         }
114 
115         // ick.
116         double z = zeroValue;
117         double mn = minimumValue;
118         double mx = maximumValue;
119         double x = (z - mn);
120         double y = (mx - z);
121         int c = colors.size();
122         int d = (c / 2);
123 
124         if ((c % 2) == 0)
125         {
126             for (int i = 1; i < d; i++)
127             {
128                 anchors.add((2 * i * x) / c);
129             }
130             anchors.add(z);
131             for (int i = d + 1; i < c; i++)
132             {
133                 anchors.add((2 * (i - d) * y) / c + z);
134             }
135         }
136         else
137         {
138             for (int i = 1; i < d + 1; i++)
139             {
140                 anchors.add((2 * i * x) / c);
141             }
142             for (int i = d + 1; i < c; i++)
143             {
144                 anchors.add(((2 * (i - d) - 1) * y) / c + z );
145             }
146         }
147     }
148 
149 
150     /**
151      * Return the name of this discrete color scheme.
152      *
153      * @return the name of this discrete color scheme
154      */
155     public String getName()
156     {
157         return name;
158     }
159 
160     @Override
161     public double getMinimumValue()
162     {
163         return minimumValue;
164     }
165 
166     @Override
167     public void setMinimumValue(final double minimumValue)
168     {
169         this.minimumValue = minimumValue;
170         recalculateAnchors();
171     }
172 
173     @Override
174     public double getMaximumValue()
175     {
176         return maximumValue;
177     }
178 
179     @Override
180     public void setMaximumValue(final double maximumValue)
181     {
182         this.maximumValue = maximumValue;
183         recalculateAnchors();
184     }
185 
186     @Override
187     public double getZeroValue()
188     {
189         return zeroValue;
190     }
191 
192     @Override
193     public void setZeroValue(final double zeroValue)
194     {
195         this.zeroValue = zeroValue;
196         recalculateAnchors();
197     }
198 
199     @Override
200     public ColorFactory getColorFactory()
201     {
202         return colorFactory;
203     }
204 
205     @Override
206     public void setColorFactory(final ColorFactory colorFactory)
207     {
208         throw new UnsupportedOperationException("setMaximumValue operation not supported by this color scheme");
209     }
210 
211     /**
212      * Return the minimum color for this color scheme.
213      *
214      * @return the minimum color for this color scheme
215      */
216     private Color getMinimumColor()
217     {
218         return colors.get(0);
219     }
220 
221     /**
222      * Return the minimum anchor for this color scheme.
223      *
224      * @return the minimum anchor for this color scheme
225      */
226     private double getMinimumAnchor()
227     {
228         return anchors.get(0);
229     }
230 
231     /**
232      * Return the maximum color for this color scheme.
233      *
234      * @return the maximum color for this color scheme
235      */
236     private Color getMaximumColor()
237     {
238         return colors.get(colors.size() - 1);
239     }
240 
241     @Override
242     public Color getColor(final double value)
243     {
244         if (value < getMinimumAnchor())
245         {
246             return getMinimumColor();
247         }
248         for (int i = 0; i < anchors.size(); i++)
249         {
250             if (value <= anchors.get(i))
251             {
252                 return colors.get(i);
253             }
254         }
255         return getMaximumColor();
256     }
257 }