Die Farbe von grün nach rot hängt vom Prozentsatz ab

86

Ich habe ein Umfragesystem und möchte, dass die Antworten für diese Umfrage farbig sind. Zum Beispiel: Wenn es 10% ist, wäre es rot, wenn 40% wäre es gelb und wenn 80% wäre es grün, also möchte ich, dass mein Javascript-Code die RGB-Farben verwendet, um eine Farbe gemäß dem angegebenen Prozentsatz zu erstellen.

function hexFromRGB(r, g, b) {
    var hex = [
        r.toString( 16 ),
        g.toString( 16 ),
        b.toString( 16 )
    ];
    $.each( hex, function( nr, val ) {
        if ( val.length === 1 ) {
            hex[ nr ] = "0" + val;
        }
    });
    return hex.join( "" ).toUpperCase();
}  

Jetzt möchte ich Hex von Prozent.

da ich bin
quelle

Antworten:

92

Dies kann mehr sein, als Sie benötigen, aber damit können Sie eine beliebige Farbkarte einrichten:

var percentColors = [
    { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },
    { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },
    { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } } ];

var getColorForPercentage = function(pct) {
    for (var i = 1; i < percentColors.length - 1; i++) {
        if (pct < percentColors[i].pct) {
            break;
        }
    }
    var lower = percentColors[i - 1];
    var upper = percentColors[i];
    var range = upper.pct - lower.pct;
    var rangePct = (pct - lower.pct) / range;
    var pctLower = 1 - rangePct;
    var pctUpper = rangePct;
    var color = {
        r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),
        g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),
        b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper)
    };
    return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
    // or output as hex if preferred
};
Jakob
quelle
1
Wow, danke Mister @Jacob ^ - ^ https://jsfiddle.net/JeancarloFontalvo/1sco9Lpe/3/
Jeancarlo Fontalvo
Genau das brauche ich für ein Projekt. Vielen Dank @Jacob!
Savado
1
Jesus, das ist unglaublich
Tallboy
Vielen Dank. Dies war gerade praktisch für ein Projekt, an dem ich arbeite!
rayalois22
124

Ein einfaches Schema mit HSL zusammen mit Geige:

function getColor(value){
    //value from 0 to 1
    var hue=((1-value)*120).toString(10);
    return ["hsl(",hue,",100%,50%)"].join("");
}

Passen Sie die Sättigung und Leuchtkraft nach Bedarf an. und eine Geige .

function getColor(value) {
  //value from 0 to 1
  var hue = ((1 - value) * 120).toString(10);
  return ["hsl(", hue, ",100%,50%)"].join("");
}
var len = 20;
for (var i = 0; i <= len; i++) {
  var value = i / len;
  var d = document.createElement('div');
  d.textContent = "value=" + value;
  d.style.backgroundColor = getColor(value);
  document.body.appendChild(d);
}

jongo45
quelle
3
Es ist also eine Black Box. Irgendeine Erklärung?
Saeed Neamati
6
Von rot nach grün. var hue = (Wert * 120) .toString (10);
Qian Chen
3
Wie können Sie dies anpassen, um einen Min- und Max-Wert einzuschließen? Zum Beispiel getColor(12,0,100)( getColor(value, min, max))?
Devil's Advocate
Scratch das, funktioniert nicht 100%: stackoverflow.com/questions/40110721/…
Devil's Advocate
@SaeedNeamati Der Farbton wird basierend auf dem von Ihnen übergebenen Wert (0 bis 1) zwischen 0 und 120 (für Rot bis Grün) festgelegt. Es konvertiert den Farbton in eine Zeichenfolge ("0" bis "120") und gibt dann eine Zeichenfolge zurück, die die Farbe im HSL-Format (Farbton, Sättigung, Helligkeit) codiert, wobei die Sättigung auf 100% und die Helligkeit auf 50% eingestellt ist.
Mattsoave
39

Sie können dies in wenigen Codezeilen (ohne Kommentare) tun, ohne dass Farbkarten erforderlich sind.

function hsl_col_perc(percent, start, end) {
  var a = percent / 100,
      b = (end - start) * a,
      c = b + start;

  // Return a CSS HSL string
  return 'hsl('+c+', 100%, 50%)';
}
//Change the start and end values to reflect the hue map
//Refernece : http://www.ncl.ucar.edu/Applications/Images/colormap_6_3_lg.png

/*
Quick ref:
    0 – red
    60 – yellow
    120 – green
    180 – turquoise
    240 – blue
    300 – pink
    360 – red
*/      

Beispiel: https://jsfiddle.net/x363g1yc/634/

Keine Notwendigkeit für Farbkarten (es sei denn, es handelt sich um eine nichtlineare Farbänderung, die nicht abgefragt wurde)

Warnung: Dies ist nicht kompatibel mit IE8 oder niedriger. (Danke Bernhard Fürst)

Mattisdada
quelle
Die Verwendung des HSL-Farbmodells ist cool, funktioniert aber in Internet Explorer 8 leider nicht.
Bernhard Fürst
Dies ist wahr, ich werde meine Antwort ändern
Mattisdada
Können Sie erklären , startund endin diesem?
Devil's Advocate
1
Nein, endist der Unterschied zwischen Start- und Endfarbe im obigen Code. hsl_col_perc(100, 60, 120)führt zu Türkis statt Grün. Sie müssen die zweite Zeile in ändern b = (end-start)*aoder sie einfach zu einem Einzeiler machen, da dies leichter zu lesen wäre.
Riv
1
Vielen Dank für die schnelle HSL-Farbreferenz!
Ohsully
13

Diese Methode funktioniert in diesem Fall gut (Prozent von 0 bis 100):

function getGreenToRed(percent){
            r = percent<50 ? 255 : Math.floor(255-(percent*2-100)*255/100);
            g = percent>50 ? 255 : Math.floor((percent*2)*255/100);
            return 'rgb('+r+','+g+',0)';
        }
zmc
quelle
6
function hexFromRGBPercent(r, g, b) {
    var hex = [
        Math.floor(r / 100 * 255).toString( 16 ),
        Math.floor(g / 100 * 255).toString( 16 ),
        Math.floor(b / 100 * 255).toString( 16 )
    ];
    $.each( hex, function( nr, val ) {
        if ( val.length === 1 ) {
            hex[ nr ] = "0" + val;
        }
    });
    return hex.join( "" ).toUpperCase();
}

Kredit geht an Andrew. Er war schneller.

Joseph Marikle
quelle
6

Ich weiß, dass dies ursprünglich eine alte Javascript-Frage ist, aber ich habe hier nach einer Lösung gesucht, die nur CSS enthält. Vielleicht hilft sie anderen gleichermaßen: Es ist eigentlich ganz einfach:

Verwenden Sie den Prozentsatz als HSL-Farbwert! Rot bis Grün überspannt H von 0bis 128(damit Sie den Prozentsatz erhöhen können, 1.2wenn Sie möchten). Beispiel:

background-color:hsl(perc,100%,50%);

Wobei Perc nur die Zahl ist, ohne das %Zeichen.

Rmaxx
quelle
3

Folgendes habe ich mir ausgedacht:

function rgbify(maxval, minval, val, moreisgood) {
    var intnsty = (val - minval) / (maxval - minval);
    var r, g;
    if (moreisgood) {
        if (intnsty > 0.5) {
            g = 255;
            r = Math.round(2 * (1 - intnsty) * 255);
        } else {
            r = 255;
            g = Math.round(2 * intnsty * 255);
        }

    } else { //lessisgood
        if (intnsty > 0.5) {
            r = 255;
            g = Math.round(2 * (1 - intnsty) * 255);
        } else {
            g = 255;
            r = Math.round(2 * intnsty * 255);
        }
    }
    return "rgb(" + r.toString() + ", " + g.toString() + ", 0)";
}

jsfiddle

Das moreisgoodFlag schaltet um, ob höhere Werte rot oder grün sein sollen. maxvalund minvalsind die Schwellenwerte für Ihren Bereich. valist der Wert, der in rgb konvertiert werden soll

keithxm23
quelle
3

Wechsel von Farbe redzu greenFarbe mit HLS. Der Wert sollte zwischen 0 und 100 liegen und in diesem Fall den Prozentsatz (%) simulieren.

function getColorFromRedToGreenByPercentage(value) {
    const hue = Math.round(value);
    return ["hsl(", hue, ", 50%, 50%)"].join("");
}
fgfernandez0321
quelle
Sehr schön, weil es anständige gedeckte Farben unterstützt, wenn Sie sie brauchen :)
Dijipiji
3

Basierend auf Jacobs Antwort habe ich eine Ladestange gemacht. Dieser ist von grün nach rot, aber Sie können die Farben ändern. Für Interessierte hier ist mein Code und die jsfiddle ( http://jsfiddle.net/rxR3x/ )

var percentColors = [
    { pct: 0, color: '#00FF00' },   { pct: 3, color: '#12FF00' },   { pct: 6, color: '#24FF00' },
    { pct: 10, color: '#47FF00' },  { pct: 13, color: '#58FF00' },  { pct: 16, color: '#6AFF00' },
    { pct: 20, color: '#7CFF00' },  { pct: 23, color: '#8DFF00' },  { pct: 26, color: '#9FFF00' },
    { pct: 30, color: '#B0FF00' },  { pct: 33, color: '#C2FF00' },  { pct: 36, color: '#D4FF00' },
    { pct: 40, color: '#E5FF00' },  { pct: 43, color: '#F7FF00' },  { pct: 46, color: '#FFF600' },
    { pct: 50, color: '#FFE400' },  { pct: 53, color: '#FFD300' },  { pct: 56, color: '#FFC100' },
    { pct: 60, color: '#FFAF00' },  { pct: 63, color: '#FF9E00' },  { pct: 66, color: '#FF8C00' },
    { pct: 70, color: '#FF7B00' },  { pct: 73, color: '#FF6900' },  { pct: 76, color: '#FF5700' },
    { pct: 80, color: '#FF4600' },  { pct: 83, color: '#FF3400' },  { pct: 86, color: '#FF2300' },
    { pct: 90, color: '#FF1100' },  { pct: 93, color: '#FF0000' },  { pct: 96, color: '#FF0000' },
    { pct: 100, color: '#FF0000' }
];
var getColorPercent = function(selector, percent, time){
    var i = 0;
    var percentInterval = setInterval(function() {
         i++;
         if(percent >= percentColors[i].pct) {
            console.log(percentColors[i].color);
            $(selector).css('background-color', percentColors[i].color);
        }
        if(percentColors[i].pct>=percent) {
            clearInterval(percentInterval);
        }
    }, time/25);
    $(selector).animate({width:(200/100)*percent}, time);
}
getColorPercent('#loadbar_storage', 100, 1500);

Aaron
quelle
2

Ändern Sie diese beiden Zeilen in Jacobs Code:

var lower = percentColors[i - 1];
var upper = percentColors[i];

zu:

var lower = (i === 0) ?  percentColors[i] : percentColors[i - 1];
var upper = (i === 0) ? percentColors[i + 1] : percentColors[i];

wenn Sie möchten, dass es für die beiden Extreme funktioniert (dh 0.0 und 1.0).

Nerfologe
quelle
2

Ich weiß, dass dies eine Art Beule zum Thema ist, aber ich habe einen weiteren Weg gefunden, dies zu tun.

Zu diesem Zweck können Sie auch eine dynamische Leinwand mit einer Dimension von 100 x 1 erstellen und einen Farbverlauf darauf anwenden. Anschließend müssen Sie aus der Funktion nur die Pixelfarbe der prozentualen Position ermitteln.

Hier ist der Code: Dies ist global:

/* dynamic canvas */

// this should be done once in a page so out of function, makes function faster
var colorBook = $('<canvas />')[0];
colorBook.width = 101;
colorBook.height = 1;
var ctx = colorBook.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, 101, 0);
grd.addColorStop(0, "rgb(255,0,0)"); //red
grd.addColorStop(0.5, "rgb(255,255,0)"); //yellow
grd.addColorStop(1, "rgb(0,255,0)"); //green    
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 101, 1);

Dann die Funktion:

function getColor(value) {
  return 'rgba(' + ctx.getImageData(Math.round(value), 0, 1, 1).data.join() + ')';
}

Demo: https://jsfiddle.net/asu09csj/

Zeus
quelle
1

HSL funktioniert in IE8 mit jquery-ui-1.10.4.

Ich habe die Antwort von jongo45 geändert, um die Leichtigkeit der Funktion zu akzeptieren.

function getColor(value, lightness) {
    //value from 0 to 1
    var hue = ((value) * 120).toString(10);
    return ["hsl(", hue, ",100%,", lightness, "%)"].join("");
}
Justin Russell
quelle
1

Der Code von Mattisdada war wirklich hilfreich für mich, als ich ein Diagramm erstellte, um Statistiken einiger Quizergebnisse anzuzeigen. Ich habe es ein wenig modifiziert, um das "Abschneiden" des Prozentsatzes zu ermöglichen (nicht sicher, was der richtige Begriff ist) und um in beide Richtungen entlang des Farbkreises zu arbeiten, z. B. sowohl von Grün (120) nach Rot (0) als auch umgekehrt.

function pickColourByScale(percent, clip, saturation, start, end)
{
    var a = (percent <= clip) ? 0 : (((percent - clip) / (100 - clip))),
        b = Math.abs(end - start) * a,
        c = (end > start) ? (start + b) : (start - b);
    return 'hsl(' + c + ','+ saturation +'%,50%)';
}

Wenn Sie einen Prozentwert festlegen, bei dem die Skalierung abgeschnitten wird, wird im Grunde alles unter diesem Wert als Startfarbe eingefärbt. Außerdem wird die Skalierung gemäß 100% - Clip neu berechnet.

Lassen Sie uns ein Beispielszenario durchgehen, in dem ich die folgenden Werte eingebe:

  • Prozent: 75
  • Clip: 50
  • Sättigung: 100 (unwichtig, ich verwende dies zum Hervorheben eines Chart.js-Diagramms)
  • Start: 0 (rot)
  • Ende: 120 (grün)

    1. Ich überprüfe, ob der Prozentsatz kleiner als der Clip ist, und gebe 0% zurück, wenn dies der Fall ist. Ansonsten berechne ich den Prozentsatz neu - 75% liegen auf halbem Weg zwischen 50% und 100%, also bekomme ich 50%. Das gibt mir 0,5.
    2. Ich verstehe den Unterschied zwischen Anfang und Ende. Sie müssen Math.abs () verwenden, wenn Ihr Startfarbwert größer als Ihr Endfarbwert ist. Dann multipliziere ich die Differenz mit dem in Schritt 1 erhaltenen Ergebnis, um zu sehen, wie viel ich brauche, um den Starttonwert zu versetzen.
    3. Wenn der Startwert größer als der Endwert ist, müssen Sie sich entlang des Farbrads in die entgegengesetzte Richtung bewegen. Addiere oder subtrahiere dem Startwert entsprechend.

Am Ende habe ich Gelb, das auf halbem Weg zwischen Rot und Grün liegt. Wenn ich die Neuberechnung in Schritt 1 nicht durchgeführt hätte, hätte ich eine grünlichere Farbe erhalten, was irreführend sein könnte.

Seyren
quelle
0

Ich habe die Antwort von zmc geändert, um einen Farbverlauf von grün (0%) nach rot (100%) zu erhalten.

const getGreenToRed = (percent) => {
    const r = 255 * percent/100;
    const g = 255 - (255 * percent/100);
    return 'rgb('+r+','+g+',0)';
}
Steve
quelle