Development Tip

녹색에서 빨간색으로 백분율에 따라 다름

yourdevel 2020. 11. 12. 20:23
반응형

녹색에서 빨간색으로 백분율에 따라 다름


설문 조사 시스템이 있고이 설문 조사에 대한 답변을 색칠하고 싶습니다. 예 : 10 %이면 빨간색, 40 %이면 노란색, 80 %이면 녹색이므로 내 자바 스크립트 코드에서 rgb 색상을 사용하여 주어진 백분율에 따라 색상을 만들도록합니다.

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

이제 퍼센트에서 16 진수를 원합니다.


필요한 것보다 많을 수 있지만 임의의 색상 맵을 설정할 수 있습니다.

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
}  

바이올린과 함께 HSL을 사용하는 간단한 계획 :

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

필요에 따라 채도와 광도를 조정합니다. 그리고 바이올린 .


색상 맵 없이도 주석을 포함하지 않고 몇 줄의 코드로이 작업을 수행 할 수 있습니다.

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
*/      

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

색상 맵이 필요하지 않습니다 (요청되지 않은 비선형 색상 변경이 아닌 경우).

경고 : 이것은 IE8 이하와 호환되지 않습니다. (Bernhard Fürst에게 감사드립니다)


이 방법은이 경우에 잘 작동합니다 (0에서 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)';
        }

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

크레딧은 앤드류에게갑니다. 그는 더 빨랐습니다.


Jacob의 코드에서 다음 두 줄을 수정합니다.

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

에:

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

두 극단 (예 : 0.0 및 1.0)에서 작동하도록하려면.


Jacobs 답변에 따라로드 바를 만들었습니다. 이것은 녹색에서 빨간색으로 바뀌지 만 색상을 변경할 수 있습니다. 관심있는 사람들을 위해 여기에 내 코드와 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);

에서 변경 redgreenHLS를 사용하여 색상. 값은 0에서 100 사이 여야하며이 경우 백분율 (%)을 시뮬레이션합니다.

function getColorFromRedToGreenByPercentage(value) {
    const hue = Math.round(value);
    return ["hsl(", hue, ", 50%, 50%)"].join("");
}

HSL은 jquery-ui-1.10.4를 사용하여 IE8에서 작동합니다.

기능에서 밝기를 허용하도록 jongo45의 답변을 수정했습니다.

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

Mattisdada's code was really helpful for me while I was making a chart to display statistics of some quiz results. I modified it a bit to allow "clipping" of the percentage (not sure what the right term is) and also to work both ways along the colour wheel, e.g. both from green(120) to red(0) and vice versa.

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

Basically, by setting a percentage value to clip the scaling at, everything below that value will be coloured as your start colour. It also recalculates the scaling according to 100% - clip.

Let's go through an example scenario where I enter the following values:

  • percent: 75
  • clip: 50
  • saturation: 100 (unimportant, I use this for highlighting a Chart.js chart)
  • start: 0 (red)
  • end: 120 (green)

    1. I check if percent is less than clip, and I return 0% if it is. Otherwise, I recalculate the percentage - 75% is halfway between 50% and 100%, so I get 50%. This gives me 0.5.
    2. I get the difference between start and end. You need to use Math.abs() in case your start hue value is more than your end hue value. Then I multiply the difference by the result obtained in step 1 to see how much I need to offset the start hue value.
    3. If the start value is more than the end value, then you need to move along the colour wheel in the opposite direction. Add to or subtract from the start value accordingly.

I end up with yellow, which is halfway between red and green. If I hadn't done the recalculation in step 1, I'd have ended up with a more greenish colour, which could be misleading.


I know this is kind of bump to topic but I found one more way of doing it.

To do this you can also create a dynamic canvas of 100x1 dimension and apply gradient to it and then from function you just need to get pixel color of the percent location.

Here is the code : This is 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);

Then the function:

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

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


This is what I came up with:

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

The moreisgood flag toggles if higher values should be red or green. maxval and minval are the threshold values for your range. val is the value to be converted to rgb

참고URL : https://stackoverflow.com/questions/7128675/from-green-to-red-color-depend-on-percentage

반응형