/**
* Copyright (C) 2001-2017 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.gui.new_plotter.utility;
import com.rapidminer.gui.new_plotter.configuration.PlotConfiguration;
import com.rapidminer.gui.new_plotter.data.PlotInstance;
import com.rapidminer.gui.new_plotter.listener.events.SeriesFormatChangeEvent;
import com.rapidminer.gui.new_plotter.listener.events.SeriesFormatChangeEvent.SeriesFormatChangeType;
import com.rapidminer.gui.new_plotter.templates.style.ColorRGB;
import java.awt.Color;
/**
* Maps real values to a color.
*
* @author Marius Helf, Nils Woehler
*
*/
public class ContinuousColorProvider implements ColorProvider {
private double minValue;
private double maxValue;
private double originalMinValue;
private double originalMaxValue;
Color minColor;
Color maxColor;
int alpha;
private boolean logarithmic;
private boolean useGrayForOutliers;
public ContinuousColorProvider(double minValue, double maxValue, Color minColor, Color maxColor, int alpha,
boolean logarithmic) {
this.minValue = minValue;
this.maxValue = maxValue;
this.originalMinValue = minValue;
this.originalMaxValue = maxValue;
this.minColor = minColor;
this.maxColor = maxColor;
this.alpha = alpha;
this.logarithmic = logarithmic;
this.useGrayForOutliers = false;
}
/**
* Default constructor sets the minimum and maximum color to the specified in the preferences.
*
*/
public ContinuousColorProvider(PlotInstance plotInstance, double minValue, double maxValue, int alpha,
boolean logarithmic) {
this.minValue = minValue;
this.maxValue = maxValue;
this.originalMinValue = minValue;
this.originalMaxValue = maxValue;
PlotConfiguration currentPlotConfigurationClone = plotInstance.getCurrentPlotConfigurationClone();
this.minColor = ColorRGB
.convertToColor(currentPlotConfigurationClone.getActiveColorScheme().getGradientStartColor());
this.maxColor = ColorRGB.convertToColor(currentPlotConfigurationClone.getActiveColorScheme().getGradientEndColor());
this.alpha = alpha;
this.logarithmic = logarithmic;
this.useGrayForOutliers = false;
}
public int getAlpha() {
return alpha;
}
public void setAlpha(int alpha) {
this.alpha = alpha;
}
public Color getMinColor() {
return minColor;
}
public void setMinColor(Color minColor) {
this.minColor = minColor;
}
public Color getMaxColor() {
return maxColor;
}
public void setMaxColor(Color maxColor) {
this.maxColor = maxColor;
}
public static Color getColorForValue(double value, int alpha, boolean logarithmic, double minValue, double maxValue,
Color minColor, Color maxColor) {
if (Double.isNaN(value)) {
return Color.LIGHT_GRAY;
}
// map value to [0,1]
if (minValue == maxValue) {
value = 0.5;
} else if (logarithmic) {
value = (Math.log(value) - Math.log(minValue)) / (Math.log(maxValue) - Math.log(minValue));
} else {
value = (value - minValue) / (maxValue - minValue);
}
Color MIN_LEGEND_COLOR = minColor;
Color MAX_LEGEND_COLOR = maxColor;
float[] minCol = Color.RGBtoHSB(MIN_LEGEND_COLOR.getRed(), MIN_LEGEND_COLOR.getGreen(), MIN_LEGEND_COLOR.getBlue(),
null);
float[] maxCol = Color.RGBtoHSB(MAX_LEGEND_COLOR.getRed(), MAX_LEGEND_COLOR.getGreen(), MAX_LEGEND_COLOR.getBlue(),
null);
double hColorDiff = maxCol[0] - minCol[0];
double sColorDiff = maxCol[1] - minCol[1];
double bColorDiff = maxCol[2] - minCol[2];
Color color = new Color(Color.HSBtoRGB((float) (minCol[0] + hColorDiff * value), (float) (minCol[1] + value
* sColorDiff), (float) (minCol[2] + value * bColorDiff)));
if (alpha < 255) {
color = DataStructureUtils.setColorAlpha(color, alpha);
}
return color;
}
@Override
public Color getColorForValue(double value) {
if (Double.isNaN(value)) {
return Color.LIGHT_GRAY;
}
// map value to [0,1]
if (minValue == maxValue) {
value = 0.5;
} else if (value < minValue) {
Color minColor;
if (useGrayForOutliers) {
minColor = Color.GRAY;
} else {
minColor = this.minColor;
}
if (alpha < 255) {
minColor = DataStructureUtils.setColorAlpha(minColor, alpha);
}
return minColor;
} else if (value > maxValue) {
Color maxColor;
if (useGrayForOutliers) {
maxColor = Color.GRAY;
} else {
maxColor = this.maxColor;
}
if (alpha < 255) {
maxColor = DataStructureUtils.setColorAlpha(maxColor, alpha);
}
return maxColor;
} else if (logarithmic) {
value = (Math.log(value) - Math.log(minValue)) / (Math.log(maxValue) - Math.log(minValue));
} else {
value = (value - minValue) / (maxValue - minValue);
}
Color MIN_LEGEND_COLOR = getMinColor();
Color MAX_LEGEND_COLOR = getMaxColor();
float[] minCol = Color.RGBtoHSB(MIN_LEGEND_COLOR.getRed(), MIN_LEGEND_COLOR.getGreen(), MIN_LEGEND_COLOR.getBlue(),
null);
float[] maxCol = Color.RGBtoHSB(MAX_LEGEND_COLOR.getRed(), MAX_LEGEND_COLOR.getGreen(), MAX_LEGEND_COLOR.getBlue(),
null);
double hColorDiff = maxCol[0] - minCol[0];
double sColorDiff = maxCol[1] - minCol[1];
double bColorDiff = maxCol[2] - minCol[2];
Color color = new Color(Color.HSBtoRGB((float) (minCol[0] + hColorDiff * value), (float) (minCol[1] + value
* sColorDiff), (float) (minCol[2] + value * bColorDiff)));
if (alpha < 255) {
color = DataStructureUtils.setColorAlpha(color, alpha);
}
return color;
}
@Override
public boolean supportsCategoricalValues() {
return false;
}
@Override
public boolean supportsNumericalValues() {
return true;
}
@Override
public ColorProvider clone() {
return new ContinuousColorProvider(minValue, maxValue, new Color(minColor.getRed(), minColor.getGreen(),
minColor.getBlue()), new Color(maxColor.getRed(), maxColor.getGreen(), maxColor.getBlue()), alpha,
logarithmic);
}
@Override
public void seriesFormatChanged(SeriesFormatChangeEvent e) {
if (e.getType() == SeriesFormatChangeType.OPACITY) {
this.alpha = e.getOpacity();
}
}
public void setLogarithmic(boolean logarithmic) {
this.logarithmic = logarithmic;
}
public double getMaxValue() {
return maxValue;
}
public void setMaxValue(double maxValue) {
this.maxValue = maxValue;
}
public double getMinValue() {
return minValue;
}
public void setMinValue(double minValue) {
this.minValue = minValue;
}
public void revertMinAndMaxValuesBackToOriginalValues() {
this.minValue = originalMinValue;
this.maxValue = originalMaxValue;
}
public boolean isUseGrayForOutliers() {
return useGrayForOutliers;
}
public void setUseGrayForOutliers(boolean useGrayForOutliers) {
this.useGrayForOutliers = useGrayForOutliers;
}
public boolean isColorMinMaxValueDifferentFromOriginal(double minValue, double maxValue) {
return !(minValue == originalMinValue && maxValue == originalMaxValue);
}
}