/*
* #%L
* gitools-utils
* %%
* Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package org.gitools.utils.colorscale.impl;
import org.gitools.utils.colorscale.ColorConstants;
import org.gitools.utils.colorscale.ColorScaleRange;
import org.gitools.utils.colorscale.NumericColorScale;
import org.gitools.utils.cutoffcmp.CutoffCmp;
import org.gitools.utils.xml.adapter.ColorXmlAdapter;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class BinaryColorScale extends NumericColorScale {
private String comparator;
private double cutoff;
@XmlJavaTypeAdapter(ColorXmlAdapter.class)
private Color minColor;
@XmlJavaTypeAdapter(ColorXmlAdapter.class)
private Color maxColor;
private static final List<CutoffCmp> equalCmp = new ArrayList<>();
static {
equalCmp.add(CutoffCmp.EQ);
equalCmp.add(CutoffCmp.ABS_EQ);
}
private static final List<CutoffCmp> notequalCmp = new ArrayList<>();
{
notequalCmp.add(CutoffCmp.NE);
notequalCmp.add(CutoffCmp.ABS_NE);
}
private static final List<CutoffCmp> absoluteCmp = new ArrayList<>();
{
absoluteCmp.add(CutoffCmp.ABS_GE);
absoluteCmp.add(CutoffCmp.ABS_LE);
absoluteCmp.add(CutoffCmp.ABS_EQ);
absoluteCmp.add(CutoffCmp.ABS_GT);
absoluteCmp.add(CutoffCmp.ABS_LT);
absoluteCmp.add(CutoffCmp.ABS_NE);
}
private BinaryColorScale(double cutoff, CutoffCmp cmp) {
super();
this.comparator = cmp.getShortName();
this.cutoff = cutoff;
}
public BinaryColorScale() {
this(1.0, CutoffCmp.EQ);
}
@Override
protected Color colorOf(double value) {
boolean satisfies = CutoffCmp.getFromName(comparator).compare(value, cutoff);
return satisfies ? getMaxColor() : getMinColor();
}
@Override
public double[] getPoints() {
double edge = Math.abs(cutoff) * 1.5;
if (edge < 0.5) {
edge = 0.5;
}
return new double[]{-edge, cutoff, edge};
}
@Override
protected void updateRangesList() {
ArrayList<ColorScaleRange> rangesList = getInternalScaleRanges();
rangesList.clear();
CutoffCmp positiveCmp = CutoffCmp.getFromName(comparator);
CutoffCmp negativeCmp = CutoffCmp.getOpposite(positiveCmp);
double outsideRange;
double insideRange;
double cutoffForRanges;
if (absoluteCmp.contains(positiveCmp)) {
cutoffForRanges = Math.abs(cutoff);
} else {
cutoffForRanges = cutoff;
}
if (cutoffForRanges != Double.POSITIVE_INFINITY && cutoffForRanges != Double.NEGATIVE_INFINITY) {
outsideRange = (cutoffForRanges == 0.0) ? Math.abs(cutoffForRanges) + 0.5 : cutoffForRanges * 2.5;
if (cutoffForRanges == 0.0) {
insideRange = -0.8;
} else {
insideRange = cutoffForRanges - cutoffForRanges * 0.5;
}
} else if (cutoffForRanges == Double.POSITIVE_INFINITY) {
outsideRange = 0.0;
insideRange = Double.POSITIVE_INFINITY;
} else {
outsideRange = 0.0;
insideRange = Double.NEGATIVE_INFINITY;
}
double positiveValue;
double negativeValue;
if (positiveCmp.compare(outsideRange, cutoffForRanges)) {
negativeValue = insideRange;
positiveValue = outsideRange;
} else {
negativeValue = outsideRange;
positiveValue = insideRange;
}
if (!positiveCmp.compare(insideRange, cutoffForRanges) && equalCmp.contains(positiveCmp)) {
positiveValue = cutoffForRanges;
} else if (positiveCmp.compare(negativeValue, cutoffForRanges) && notequalCmp.contains(positiveCmp)) {
negativeValue = cutoffForRanges;
}
ColorScaleRange positiveRange = new ColorScaleRange(positiveValue, positiveValue, 3);
positiveRange.setType(ColorScaleRange.CONSTANT_TYPE);
positiveRange.setCenterLabel(positiveCmp.getShortName() + " " + Double.toString(cutoffForRanges));
ColorScaleRange empty = new ColorScaleRange(0, 0, 1);
empty.setType(ColorScaleRange.EMPTY_TYPE);
empty.setBorderEnabled(false);
ColorScaleRange negativeRange = new ColorScaleRange(negativeValue, negativeValue, 3);
negativeRange.setType(ColorScaleRange.CONSTANT_TYPE);
negativeRange.setCenterLabel(negativeCmp.getShortName() + " " + Double.toString(cutoffForRanges));
rangesList.add(empty);
rangesList.add(positiveRange);
rangesList.add(empty);
rangesList.add(negativeRange);
rangesList.add(empty);
}
public Color getMinColor() {
if (minColor == null) {
return ColorConstants.binaryMinColor;
}
return minColor;
}
public void setMinColor(Color minColor) {
this.minColor = minColor;
}
public Color getMaxColor() {
if (maxColor == null) {
return ColorConstants.binaryMaxColor;
}
return maxColor;
}
public void setMaxColor(Color maxColor) {
this.maxColor = maxColor;
}
public String getComparator() {
return comparator;
}
public void setComparator(String comparator) {
this.comparator = comparator;
updateRangesList();
}
public double getCutoff() {
return cutoff;
}
public void setCutoff(double cutoff) {
this.cutoff = cutoff;
updateRangesList();
}
}