từ màu xanh lá cây đến màu đỏ phụ thuộc vào tỷ lệ phần trăm


84

Tôi có một hệ thống thăm dò ý kiến ​​và tôi muốn có các câu trả lời cho cuộc thăm dò ý kiến ​​này. Ví dụ: Nếu là 10% thì nó sẽ là màu đỏ, nếu 40% thì nó sẽ là màu vàng và nếu là 80% thì nó sẽ là xanh lục, vì vậy tôi muốn mã javascript của mình sử dụng các màu rgb để tạo ra một màu theo phần trăm đã cho.

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

Bây giờ tôi muốn hex từ phần trăm.


Câu trả lời:


87

Điều này có thể nhiều hơn bạn cần, nhưng điều này cho phép bạn thiết lập bất kỳ bản đồ màu tùy ý nào:

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


Đây chính xác là những gì tôi cần cho một dự án. Cảm ơn bạn @Jacob rất nhiều!
Savado

1
Chúa
ơi,

Cảm ơn rất nhiều. Điều này chỉ hữu ích cho một dự án mà tôi đang thực hiện!
rayalois 22

122

Một sơ đồ đơn giản sử dụng HSL cùng với fiddle:

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

điều chỉnh độ bão hòa và độ sáng khi cần thiết. và một trò đùa .

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


3
Vì vậy, nó là một hộp đen. Bất kỳ lời giải thích?
Saeed Neamati vào

6
Từ đỏ sang xanh lục. var hue = (value * 120) .toString (10);
Qian Chen

3
Làm thế nào bạn có thể điều chỉnh điều này để bao gồm giá trị tối thiểu và giá trị tối đa? Ví dụ, getColor(12,0,100)( getColor(value, min, max))?
Devil's Advocate,

Cào mà không hoạt động 100%: stackoverflow.com/questions/40110721/…
Devil's Advocate,

@SaeedNeamati Nó đặt màu từ 0 đến 120 (đại diện cho màu đỏ đến màu xanh lá cây) dựa trên giá trị bạn chuyển (0 đến 1). Nó chuyển đổi màu sắc thành một chuỗi ("0" đến "120"), sau đó trả về một chuỗi mã hóa màu ở định dạng hsl (màu sắc, độ bão hòa, độ đậm nhạt), với độ bão hòa được đặt thành 100% và độ sáng được đặt thành 50%.
mattsoave

38

Bạn có thể thực hiện việc này trong một vài dòng mã (không bao gồm chú thích) mà không cần bất kỳ bản đồ màu nào.

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

Ví dụ: https://jsfiddle.net/x363g1yc/634/

Không cần bản đồ màu (Trừ khi đó là sự thay đổi màu phi tuyến tính, không được yêu cầu)

Cảnh báo: Điều này không tương thích với IE8 trở xuống. (Cảm ơn Bernhard Fürst)


Rất tiếc, sử dụng mô hình màu HSL rất tuyệt nhưng nó không hoạt động trong Internet Explorer 8.
Bernhard Fürst

Điều này đúng, tôi sẽ sửa đổi câu trả lời của tôi
Mattisdada

Bạn có thể giải thích startendtrong này?
Devil's Advocate,

1
Không, endlà sự khác biệt giữa màu bắt đầu và màu kết thúc trong đoạn mã trên. hsl_col_perc(100, 60, 120)sẽ dẫn đến màu xanh ngọc lam thay vì màu xanh lục. Bạn cần thay đổi dòng thứ hai thành b = (end-start)*ahoặc chỉ làm cho nó thành một dòng kẻ vì điều đó sẽ dễ đọc hơn.
riv

1
Cảm ơn bạn đã để lại trong bản giới thiệu màu HSL nhanh chóng!
ohsully

13

Phương pháp này hoạt động tốt trong trường hợp này (phần trăm từ 0 đến 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)';
        }

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

Tín dụng được chuyển đến andrew. Anh ấy đã nhanh hơn.


5

Tôi biết đây ban đầu là một câu hỏi javascript cũ, nhưng tôi đến đây để tìm kiếm giải pháp chỉ CSS , vì vậy có thể nó sẽ giúp ích cho những người khác như nhau: Nó thực sự khá đơn giản:

Sử dụng phần trăm như một giá trị màu HSL! Red đến Green kéo dài từ H 0đến 128. (Vì vậy bạn có thể tăng tỷ lệ phần trăm lên 1.2nếu bạn muốn). Thí dụ:

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

Trong đó perc chỉ là số, không có %dấu.


3

Đây là những gì tôi đã nghĩ ra:

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

Các moreisgoodToggles cờ nếu giá trị cao hơn nên màu đỏ hoặc màu xanh lá cây. maxvalminvallà các giá trị ngưỡng cho phạm vi của bạn. vallà giá trị được chuyển đổi thành rgb


3

Thay đổi từ redsang greenmàu bằng HLS. Giá trị phải từ 0 đến 100, trong trường hợp này là mô phỏng phần trăm (%).

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

Rất thoải mái vì nó hỗ trợ màu sắc tắt phong nha nếu bạn cần chúng :)
dijipiji

3

Dựa trên câu trả lời của Jacobs, tôi đã tạo một thanh tải. Cái này có màu từ xanh sang đỏ, nhưng bạn có thể thay đổi màu sắc. Đối với những người quan tâm, đây là mã của tôi và 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);


2

Sửa đổi hai dòng này trong mã của Jacob:

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

đến:

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

nếu bạn muốn làm cho nó hoạt động cho hai cực (tức là 0,0 và 1,0).


2

Tôi biết đây là một chủ đề khá rắc rối nhưng tôi đã tìm thấy một cách khác để làm điều đó.

Để làm điều này, bạn cũng có thể tạo một canvas động có kích thước 100x1 và áp dụng gradient cho nó và sau đó từ chức năng, bạn chỉ cần lấy màu pixel của vị trí phần trăm.

Đây là mã: Đây là toàn cầu:

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

Sau đó, hàm:

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

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


1

HSL sẽ hoạt động trong IE8 bằng jquery-ui-1.10.4.

Tôi đã sửa đổi câu trả lời của jongo45 để chấp nhận độ nhẹ trong hàm.

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

1

Mã của Mattisdada thực sự hữu ích cho tôi khi tôi đang lập biểu đồ để hiển thị số liệu thống kê của một số kết quả bài kiểm tra. Tôi đã sửa đổi nó một chút để cho phép "cắt bớt" tỷ lệ phần trăm (không chắc chắn thuật ngữ phù hợp là gì) và cũng hoạt động theo cả hai cách dọc theo bánh xe màu, ví dụ cả từ màu xanh lá cây (120) sang màu đỏ (0) và ngược lại.

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

Về cơ bản, bằng cách đặt giá trị phần trăm để cắt tỷ lệ ở mức, mọi thứ bên dưới giá trị đó sẽ được tô màu làm màu bắt đầu của bạn. Nó cũng tính toán lại tỷ lệ theo 100% - clip.

Hãy xem qua một tình huống ví dụ mà tôi nhập các giá trị sau:

  • phần trăm: 75
  • clip: 50
  • bão hòa: 100 (không quan trọng, tôi sử dụng điều này để làm nổi bật biểu đồ Chart.js)
  • bắt đầu: 0 (đỏ)
  • kết thúc: 120 (xanh lục)

    1. Tôi kiểm tra xem phần trăm có nhỏ hơn clip không và tôi trả về 0% nếu đúng như vậy. Nếu không, tôi tính toán lại tỷ lệ phần trăm - 75% nằm giữa 50% và 100%, vì vậy tôi nhận được 50%. Điều này cho tôi 0,5.
    2. Tôi nhận được sự khác biệt giữa bắt đầu và kết thúc. Bạn cần sử dụng Math.abs () trong trường hợp giá trị màu sắc bắt đầu của bạn nhiều hơn giá trị màu sắc cuối cùng. Sau đó, tôi nhân sự khác biệt với kết quả thu được ở bước 1 để xem tôi cần bù đắp giá trị màu sắc bắt đầu là bao nhiêu.
    3. Nếu giá trị bắt đầu nhiều hơn giá trị kết thúc, thì bạn cần di chuyển dọc theo bánh xe màu theo hướng ngược lại. Thêm vào hoặc trừ khỏi giá trị bắt đầu cho phù hợp.

Tôi kết thúc với màu vàng, nằm giữa màu đỏ và xanh lá cây. Nếu tôi không thực hiện tính toán lại ở bước 1, tôi sẽ có một màu xanh lục hơn, có thể gây hiểu nhầm.


0

Tôi đã sửa đổi câu trả lời của zmc để tạo ra một gradient từ màu xanh lá cây (0%) sang màu đỏ (100%).

const getGreenToRed = (percent) => {
    const r = 255 * percent/100;
    const g = 255 - (255 * percent/100);
    return 'rgb('+r+','+g+',0)';
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.