001/* =========================================================== 002 * Orson Charts : a 3D chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C)opyright 2013-2022, by David Gilbert. All rights reserved. 006 * 007 * https://github.com/jfree/orson-charts 008 * 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as published by 011 * the Free Software Foundation, either version 3 of the License, or 012 * (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 021 * 022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 023 * Other names may be trademarks of their respective owners.] 024 * 025 * If you do not wish to be bound by the terms of the GPL, an alternative 026 * commercial license can be purchased. For details, please see visit the 027 * Orson Charts home page: 028 * 029 * http://www.object-refinery.com/orsoncharts/index.html 030 * 031 */ 032 033package org.jfree.chart3d.renderer; 034 035import java.awt.Color; 036 037import org.jfree.chart3d.data.Range; 038import org.jfree.chart3d.internal.Args; 039 040/** 041 * A color scale that runs a linear gradient between two colors. 042 * <br><br> 043 * NOTE: This class is serializable, but the serialization format is subject 044 * to change in future releases and should not be relied upon for persisting 045 * instances of this class. 046 * 047 * @since 1.1 048 */ 049@SuppressWarnings("serial") 050public class GradientColorScale extends AbstractColorScale 051 implements ColorScale { 052 053 /** The color at the low end of the value range. */ 054 private final Color lowColor; 055 056 /** The color at the high end of the value range. */ 057 private final Color highColor; 058 059 /** Storage for the color samples. */ 060 private final Color[] colors; 061 062 /** 063 * Creates a new instance with the specified value range and colors. 064 * 065 * @param range the data value range ({@code null} not permitted). 066 * @param lowColor the color for the low end of the data range 067 * ({@code null} not permitted). 068 * @param highColor the color for the high end of the data range 069 * ({@code null} not permitted). 070 */ 071 public GradientColorScale(Range range, Color lowColor, Color highColor) { 072 super(range); 073 Args.nullNotPermitted(lowColor, "lowColor"); 074 Args.nullNotPermitted(highColor, "highColor"); 075 this.lowColor = lowColor; 076 this.highColor = highColor; 077 this.colors = new Color[255]; 078 } 079 080 /** 081 * Returns the color for the low end of the data value range. 082 * 083 * @return The color (never {@code null}). 084 */ 085 public Color getLowColor() { 086 return this.lowColor; 087 } 088 089 /** 090 * Returns the color for the high end of the data value range. 091 * 092 * @return The color (never {@code null}). 093 */ 094 public Color getHighColor() { 095 return this.highColor; 096 } 097 098 /** 099 * Returns the number of samples used by this color scale. 100 * 101 * @return The number of samples. 102 */ 103 public int getSampleCount() { 104 return this.colors.length; 105 } 106 107 /** 108 * Returns the color corresponding to the specified data value. If this 109 * 110 * @param value the data value. 111 * 112 * @return The color (never {@code null}). 113 */ 114 @Override 115 public Color valueToColor(double value) { 116 Range r = getRange(); 117 if (value < r.getMin()) { 118 return valueToColor(r.getMin()); 119 } 120 if (value > r.getMax()) { 121 return valueToColor(r.getMax()); 122 } 123 double fraction = getRange().percent(value); 124 int i = Math.min((int) (fraction * this.colors.length), 125 this.colors.length - 1); 126 if (this.colors[i] == null) { 127 float[] lrgba = this.lowColor.getRGBComponents(null); 128 float[] hrgba = this.highColor.getRGBComponents(null); 129 float p = (float) fraction; 130 this.colors[i] = new Color(lrgba[0] * (1 - p) + hrgba[0] * p, 131 lrgba[1] * (1 - p) + hrgba[1] * p, 132 lrgba[2] * (1 - p) + hrgba[2] * p, 133 lrgba[3] * (1 - p) + hrgba[3] * p); 134 } 135 return this.colors[i]; 136 } 137 138 /** 139 * Tests this instance for equality with an arbitrary object. 140 * 141 * @param obj the object ({@code null} permitted). 142 * 143 * @return A boolean. 144 */ 145 @Override 146 public boolean equals(Object obj) { 147 if (obj == this) { 148 return true; 149 } 150 if (!(obj instanceof GradientColorScale)) { 151 return false; 152 } 153 GradientColorScale that = (GradientColorScale) obj; 154 if (!this.lowColor.equals(that.lowColor)) { 155 return false; 156 } 157 if (!this.highColor.equals(that.highColor)) { 158 return false; 159 } 160 return super.equals(obj); 161 } 162 163}