Formatage conditionnel-conversion du pourcentage en couleur
Quelle est la meilleure façon de convertir un pourcentage en une couleur allant du Vert (100%) au rouge (0%), avec du jaune pour 50%?
j'utilise 32bit RGB - donc chaque composant est un entier entre 0 et 255. Je fais ça en C#, mais je suppose que pour un problème comme celui-ci, la langue n'a pas vraiment d'importance.
basé sur les réponses de Marius et Andy j'utilise la solution suivante:
double red = (percent < 50) ? 255 : 256 - (percent - 50) * 5.12;
double green = (percent > 50) ? 255 : percent * 5.12;
var color = Color.FromArgb(255, (byte)red, (byte)green, 0);
fonctionne parfaitement - Le seul ajustement que J'ai eu à faire à partir de la solution de Marius était d'utiliser 256, comme (255 - (pour cent - 50) * 5.12 rendement -1 quand 100%, résultant en jaune pour une raison quelconque dans Silverlight (-1, 255, 0) -> Jaune ...
9 réponses
j'ai fait cette fonction en JavaScript. Il renvoie la couleur est une chaîne css. Il prend le pourcentage de la variable avec une plage de 0 à 100. L'algorithme pourrait être fait dans n'importe quelle langue:
function setColor(p){
var red = p<50 ? 255 : Math.round(256 - (p-50)*5.12);
var green = p>50 ? 255 : Math.round((p)*5.12);
return "rgb(" + red + "," + green + ",0)";
}
ce que vous voulez probablement faire est d'assigner votre 0% à 100% de points dans un espace de couleur HSV ou HSL. De là, vous pouvez interpoler les couleurs (et le jaune se trouve juste entre le rouge et le vert :) et les convertir en RGB . Cela vous donnera une belle pente entre les deux.
en supposant que vous utiliserez la couleur comme indicateur de statut et du point de vue de l'interface utilisateur, cependant, ce n'est probablement pas une si bonne idée, puisque nous sommes assez mauvais pour voir de petits changements de couleur. Ainsi, diviser la valeur en, par exemple, trois à sept seaux vous donnerait des différences plus visibles lorsque les choses changent, au prix d'une certaine précision (que vous ne seriez probablement pas en mesure d'apprécier de toute façon).
donc, toutes les maths mises à part, à la fin je recommanderais une table de recherche avec les couleurs suivantes avec v étant la valeur d'entrée:
#e7241d for v <= 12%
#ef832c for v > 12% and v <= 36%
#fffd46 for v > 36% and v <= 60%
#9cfa40 for v > 60% and v <= 84%
#60f83d for v > 84%
ceux-ci ont été très naïvement convertie à partir des valeurs HSL (0.0, 1.0, 1.0), (30.0, 1.0, 1.0), (60.0, 1.0, 1.0), (90.0, 1.0, 1.0), (120.0, 1.0, 1.0), et vous pourriez vouloir ajuster les couleurs un peu pour convenir à vos buts (certains n'aiment pas que le rouge et le vert ne sont pas 'pur').
s'il vous Plaît voir:
- utilisant la couleur HSL (Teinte, Saturation, luminosité) pour créer des interfaces graphiques plus attrayantes pour quelques discussions et
- RGB et LGV Conversions d'Espace de Couleur pour l'échantillon C# code source.
en pseudo-code.
-
à partir de 0-50% votre valeur hex serait FFxx00 où:
XX = ( Percentage / 50 ) * 255 converted into hex.
-
de 50 à 100 votre valeur hexadécimale serait xxFF00 où:
XX = ((100-Percentage) / 50) * 255 converted into hex.
L'espoir qui aide et est compréhensible.
il s'agit d'une bonne solution propre qui améliore la réponse actuellement acceptée de trois façons:
- supprime le nombre magique (5.12), rendant ainsi le code plus facile à suivre.
- ne produira pas l'erreur d'arrondissement qui vous donne -1 quand le pourcentage est de 100%.
- vous permet de personnaliser les valeurs RGB minimum et maximum que vous utilisez, de sorte que vous pouvez produire une gamme plus légère ou plus foncée que RGB simple(255, 0, 0) - rgb (0, 255, 0).
le code affiché est C# mais il est trivial d'adapter l'algorithme à n'importe quel autre langage.
private const int RGB_MAX = 255; // Reduce this for a darker range
private const int RGB_MIN = 0; // Increase this for a lighter range
private Color getColorFromPercentage(int percentage)
{
// Work out the percentage of red and green to use (i.e. a percentage
// of the range from RGB_MIN to RGB_MAX)
var redPercent = Math.Min(200 - (percentage * 2), 100) / 100f;
var greenPercent = Math.Min(percentage * 2, 100) / 100f;
// Now convert those percentages to actual RGB values in the range
// RGB_MIN - RGB_MAX
var red = RGB_MIN + ((RGB_MAX - RGB_MIN) * redPercent);
var green = RGB_MIN + ((RGB_MAX - RGB_MIN) * greenPercent);
return Color.FromArgb(red, green, RGB_MIN);
}
Notes
voici un tableau simple montrant quelques valeurs en pourcentage, et les proportions correspondantes rouge et vert que nous voulons produire:
VALUE GREEN RED RESULTING COLOUR
100% 100% 0% green
75% 100% 50% yellowy green
50% 100% 100% yellow
25% 50% 100% orange
0% 0% 100% red
j'espère que vous pouvez voir assez clairement que
- la valeur verte est 2x le pourcentage valeur (mais plafonnée à 100)"
- le rouge est l'inverse: 2x (100 - pourcentage) (mais plafonné à 100)
ainsi mon algorithme calcule les valeurs d'une table ressemblant à quelque chose comme ceci...
VALUE GREEN RED
100% 200% 0%
75% 150% 50%
50% 100% 100%
25% 50% 150%
0% 0% 200%
...et puis utilise Math.Min()
pour les plafonner à 100%.
j'ai écrit cette fonction python basée sur le code javascript. il prend un pourcentage comme une décimale. j'ai aussi carré la valeur pour garder les couleurs rouge pour plus longtemps en bas de l'échelle de pourcentage. J'ai aussi réduit la gamme de couleurs de 255 à 180 pour donner un rouge foncé et vert à chaque extrémité. ceux-ci peuvent être joués pour donner de belles couleurs. Je voudrais ajouter une touche d'orange dans le milieu, mais je dois faire un travail correct, boo.
def getBarColour(value):
red = int( (1 - (value*value) ) * 180 )
green = int( (value * value )* 180 )
red = "%02X" % red
green = "%02X" % green
return '#' + red + green +'00'
comme le jaune est un mélange de rouge et de vert, vous pouvez probablement commencer par #F00
et ensuite glisser le vert jusqu'à ce que vous appuyez sur #FF0
, puis glisser le rouge vers le bas à #0F0
:
for (int i = 0; i < 100; i++) {
var red = i < 50
? 255
: 255 - (256.0 / 100 * ((i - 50) * 2));
var green = i < 50
? 256.0 / 100 * (i * 2)
: 255;
var col = Color.FromArgb((int) red, (int) green, 0);
}
j'utilise les routines Python suivantes pour passer d'une couleur à l'autre:
def blendRGBHex(hex1, hex2, fraction):
return RGBDecToHex(blendRGB(RGBHexToDec(hex1),
RGBHexToDec(hex2), fraction))
def blendRGB(dec1, dec2, fraction):
return [int(v1 + (v2-v1)*fraction)
for (v1, v2) in zip(dec1, dec2)]
def RGBHexToDec(hex):
return [int(hex[n:n+2],16) for n in range(0,len(hex),2)]
def RGBDecToHex(dec):
return "".join(["%02x"%d for d in dec])
par exemple:
>>> blendRGBHex("FF8080", "80FF80", 0.5)
"BFBF80"
une autre routine l'enveloppe pour bien se fondre entre les valeurs numériques de "conditional formatting":
def colourRange(minV, minC, avgV, avgC, maxV, maxC, v):
if v < minV: return minC
if v > maxV: return maxC
if v < avgV:
return blendRGBHex(minC, avgC, (v - minV)/(avgV-minV))
elif v > avgV:
return blendRGBHex(avgC, maxC, (v - avgV)/(maxV-avgV))
else:
return avgC
donc, dans le cas de Jonas:
>>> colourRange(0, "FF0000", 50, "FFFF00", 100, "00FF00", 25)
"FF7F00"
ma solution pour ActionScript 3:
var red:Number = (percentage <= 50) ? 255 : 256 - (percentage - 50) * 5.12;
var green:Number = (percentage >= 50) ? 255 : percentage * 5.12;
var redHex:Number = Math.round(red) * 0x10000;
var greenHex:Number = Math.round(green) * 0x100;
var colorToReturn:uint = redHex + greenHex;
parce que C'est R-G-B, les couleurs vont de valeurs entières de -1 (blanc), à -16777216 pour le noir. avec du vert rouge et du jaune quelque part au milieu. Le jaune est en fait -256, tandis que le rouge est -65536 et le vert est -16744448. Donc le jaune n'est pas entre le rouge et le vert dans la notation du RVB. Je sais qu'en termes de wavelenghts, le vert d'un côté et rouge de l'autre côté du spectre, mais je n'ai jamais vu ce type de notation utilisé dans les ordinateurs, que le spectre n'est pas représenter toutes les couleurs visibles.