001/*-------------------------------------------------------------------------+ 002| | 003| Copyright 2005-2011 the ConQAT Project | 004| | 005| Licensed under the Apache License, Version 2.0 (the "License"); | 006| you may not use this file except in compliance with the License. | 007| You may obtain a copy of the License at | 008| | 009| http://www.apache.org/licenses/LICENSE-2.0 | 010| | 011| Unless required by applicable law or agreed to in writing, software | 012| distributed under the License is distributed on an "AS IS" BASIS, | 013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 014| See the License for the specific language governing permissions and | 015| limitations under the License. | 016+-------------------------------------------------------------------------*/ 017package org.conqat.lib.commons.assessment; 018 019import java.awt.Color; 020import java.text.DecimalFormat; 021import java.text.NumberFormat; 022import java.util.ArrayList; 023import java.util.List; 024 025import org.conqat.lib.commons.color.ECCSMColor; 026 027/** 028 * Utility methods for dealing with ratings. 029 */ 030public class AssessmentUtils { 031 032 /** Number format that adds + or - as necessary. */ 033 public static final NumberFormat PLUS_MINUS_NUMBERFORMAT = new DecimalFormat("+#;-#"); 034 035 /** Returns the color used for visualizing a traffic light color. */ 036 public static Color getColor(ETrafficLightColor color) { 037 switch (color) { 038 case RED: 039 return ECCSMColor.RED.getColor(); 040 case YELLOW: 041 return ECCSMColor.YELLOW.getColor(); 042 case GREEN: 043 return ECCSMColor.GREEN.getColor(); 044 case BASELINE: 045 return ECCSMColor.LIGHT_BLUE.getColor(); 046 047 case UNKNOWN: 048 default: 049 return ECCSMColor.DARK_GRAY.getColor(); 050 } 051 } 052 053 /** 054 * Compares two {@link Assessment}s returning which is "better" than another 055 * one. 056 * 057 * @return the value 0 if o1 is equal to o2; a value less than 0 if o1 is worse 058 * than o2; and a value greater than 0 if o1 is better than o2. 059 */ 060 public static int compareAssessments(Assessment o1, Assessment o2) { 061 double red1 = o1.getColorFrequency(ETrafficLightColor.RED) / (double) o1.getSize(); 062 double red2 = o2.getColorFrequency(ETrafficLightColor.RED) / (double) o2.getSize(); 063 double yellow1 = o1.getColorFrequency(ETrafficLightColor.YELLOW) / (double) o1.getSize(); 064 double yellow2 = o2.getColorFrequency(ETrafficLightColor.YELLOW) / (double) o2.getSize(); 065 066 // chosen by a close look at the sorting result. 067 double yFactor = 0.4; 068 return Double.compare(red1 + yFactor * yellow1, red2 + yFactor * yellow2); 069 } 070 071 /** 072 * Calculates a delta string for two given assessments. Only colors RED, YELLOW 073 * and GREEN. 074 */ 075 public static String calculateAndFormatDelta(Assessment oldAssessment, Assessment newAssessment) { 076 List<String> builder = new ArrayList<>(); 077 for (ETrafficLightColor color : ETrafficLightColor.getTrafficLightColors()) { 078 if (computeRelativeFrequencyDelta(color, oldAssessment, newAssessment) == 0) { 079 continue; 080 } 081 builder.add(calculateAndFormatDelta(color, oldAssessment, newAssessment)); 082 } 083 return String.join(", ", builder); 084 } 085 086 /** 087 * Calculates a delta string for a given color for two given assessments 088 * containing the color frequency delta and the relative delta change. 089 */ 090 public static String calculateAndFormatDelta(ETrafficLightColor color, Assessment oldAssessment, 091 Assessment newAssessment) { 092 String colorName = color.getShortDisplayText(); 093 094 String colorFrequencyDeltaFormatted = PLUS_MINUS_NUMBERFORMAT 095 .format(newAssessment.getColorFrequency(color) - oldAssessment.getColorFrequency(color)); 096 097 double colorRelativeDelta = computeRelativeFrequencyDelta(color, oldAssessment, newAssessment); 098 String colorRelativeDeltaFormatted = Assessment.PERCENT_FORMAT.format(colorRelativeDelta); 099 100 String formattedDelta = colorName + ": " + colorFrequencyDeltaFormatted + " ("; 101 if (colorRelativeDelta > 0) { 102 formattedDelta += "+"; 103 } 104 formattedDelta += colorRelativeDeltaFormatted + ")"; 105 return formattedDelta; 106 } 107 108 /** 109 * Calculate the relative color frequency delta to the given assessments 110 */ 111 public static double computeRelativeFrequencyDelta(ETrafficLightColor color, Assessment oldAssessment, 112 Assessment newAssessment) { 113 return (double) newAssessment.getColorFrequency(color) / newAssessment.getSize() 114 - (double) oldAssessment.getColorFrequency(color) / oldAssessment.getSize(); 115 } 116 117}