Domanda

Qual è il modo più semplice per convertire una percentuale in un colore che va dal verde (100%) al rosso (0%), con il giallo per il 50%?

Sto utilizzando un semplice RGB a 32 bit, quindi ogni componente è un numero intero compreso tra 0 e 255.Lo sto facendo in C#, ma immagino che per un problema come questo la lingua non abbia molta importanza.

Sulla base delle risposte di Marius e Andy, sto utilizzando la seguente soluzione:

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);

Funziona perfettamente - L'unica modifica che ho dovuto apportare alla soluzione Marius è stata quella di utilizzare 256, poiché (255 - (percentuale - 50) * 5,12 restituisce -1 al 100%, risultando in Giallo per qualche motivo in Silverlight (-1, 255, 0 ) -> Giallo...

È stato utile?

Soluzione

Ho creato questa funzione in JavaScript.Restituisce il colore è una stringa CSS.Prende la percentuale come variabile, con un intervallo compreso tra 0 e 100.L'algoritmo può essere realizzato in qualsiasi lingua:

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)";
}

Altri suggerimenti

Quello che probabilmente vorrai fare è assegnare dallo 0% al 100% alcuni punti in uno spazio colore HSV o HSL.Da lì puoi interpolare i colori (e il giallo sembra essere tra il rosso e il verde :) e convertirli in RGB.Questo ti darà un gradiente gradevole tra i due.

Supponendo che utilizzerai il colore come indicatore di stato e dal punto di vista dell'interfaccia utente, tuttavia, probabilmente non è una buona idea, dal momento che siamo piuttosto cattivi nel vedere piccoli cambiamenti nel colore.Quindi dividere il valore, ad esempio, in tre o sette intervalli ti darebbe differenze più evidenti quando le cose cambiano, al costo di una certa precisione (che molto probabilmente non saresti comunque in grado di apprezzare).

Quindi, matematica a parte, alla fine consiglierei una tabella di ricerca con i seguenti colori con v come valore di input:

#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%

Questi sono stati convertiti in modo molto ingenuo dai valori 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) e potresti voler regolare un po' i colori per adattarli ai tuoi scopi (ad alcuni non piace che il rosso e il verde non siano "puri").

Perfavore guarda:

In pseudocodice.

  • Da 0-50% il tuo valore esadecimale sarebbe FFxx00 dove:

    XX = ( Percentage / 50 ) * 255 converted into hex.
    
  • Da 50 a 100 il tuo valore esadecimale sarebbe xxFF00 dove:

    XX = ((100-Percentage) / 50) * 255 converted into hex.  
    

Spero che questo aiuti e sia comprensibile.

Questa è una bella soluzione pulita che migliora la risposta attualmente accettata in tre modi:

  1. Rimuove il numero magico (5.12), rendendo quindi il codice più facile da seguire.
  2. Non produrrà l'errore di arrotondamento che ti dà -1 quando la percentuale è al 100%.
  3. Consente di personalizzare i valori RGB minimi e massimi utilizzati, in modo da poter produrre un intervallo più chiaro o più scuro rispetto al semplice rgb(255, 0, 0) - rgb(0, 255, 0).

Il codice mostrato è C# ma è banale adattare l'algoritmo a qualsiasi altro linguaggio.

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);
}

Appunti

Ecco una semplice tabella che mostra alcuni valori percentuali e le corrispondenti proporzioni rosso e verde che vogliamo produrre:

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

Spero che tu possa vederlo abbastanza chiaramente

  • il valore verde è 2 volte il valore percentuale (ma limitato a 100)
  • il rosso è l'inverso:2x (100 - percentuale) (ma limitato a 100)

Quindi il mio algoritmo calcola i valori da una tabella simile a questa...

VALUE   GREEN    RED
 100%    200%     0%
  75%    150%    50%
  50%    100%   100%
  25%     50%   150%
   0%      0%   200%

...e poi usa Math.Min() per limitarli al 100%.

Ho scritto questa funzione Python in base al codice Javascript.prende una percentuale come decimale.inoltre ho quadrato il valore per mantenere i colori più rossi più a lungo nella scala percentuale.Ho anche ristretto la gamma di colori da 255 a 180 per ottenere un rosso e un verde più scuri a ciascuna estremità.con questi si può giocare per dare dei bei colori.Vorrei aggiungere un tocco di arancione al centro, ma devo andare avanti con il lavoro giusto, tesoro.

def getBarColour(value):
    red = int( (1 - (value*value) ) * 180 )
    green = int( (value * value )* 180 )

    red = "%02X" % red
    green = "%02X" % green

    return '#' + red + green +'00'

Dato che il giallo è un mix di rosso e verde, probabilmente puoi iniziare con #F00 e poi fai scorrere il verde verso l'alto finché non colpisci #FF0, quindi scorri verso il basso in rosso #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);
}

Utilizzo le seguenti routine Python per fondere i colori:

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])

Per esempio:

>>> blendRGBHex("FF8080", "80FF80", 0.5)
"BFBF80"

Un'altra routine lo avvolge per fondersi bene tra i valori numerici per la "formattazione condizionale":

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

Quindi, nel caso di Jonas:

>>> colourRange(0, "FF0000", 50, "FFFF00", 100, "00FF00", 25)
"FF7F00"

La mia soluzione per 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;

Poiché è R-G-B, i colori vanno da valori interi di -1 (bianco) a -16777216 per il nero.con rosso verde e giallo da qualche parte nel mezzo.Il giallo in realtà è -256, mentre il rosso è -65536 e il verde è -16744448.Quindi il giallo in realtà non è tra il rosso e il verde nella notazione RGB.So che in termini di lunghezze d'onda, il verde è da un lato e il rosso è dall'altro lato dello spettro, ma non ho mai visto questo tipo di notazione utilizzata nei computer, poiché lo spettro non rappresenta tutti i colori visibili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top