最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Color range - table values in angular - Stack Overflow

programmeradmin0浏览0评论

Lets assume we have the following setup (bellow), I want the table to have 5 cells, which it will, but i want the 5 cells to have a dynamic color range which goes from green to red (1 = green, 3 = yellow, 5 = red, ect)

The only technologies I am allowed to work with is : CSS3 / HTML5 / Angular - I am allowed to work with any angular lib

In excel its trivial doing this, but since im fairly new to angular, i'm admittedly a bit lost.

~ Script
var arrayWith5Values = [1,2,3,4,5]
~
    <table>
        <tr>
           <td ng-repeat='numericValue in arrayWith5Values'>
              {{numericValue}}}
           </td>
        </tr>
    </table>

It's basicly the angular version of this question : Coloring HTML table cells from "Low to High Color Shades" depending on Cell Value in Python HTML Email and this Color Cell Based on Value in Cell

I have been searching StackOverflow for the majority of last night and could not find an answer.

Here is an example (screenshot from excel)

Lets assume we have the following setup (bellow), I want the table to have 5 cells, which it will, but i want the 5 cells to have a dynamic color range which goes from green to red (1 = green, 3 = yellow, 5 = red, ect)

The only technologies I am allowed to work with is : CSS3 / HTML5 / Angular - I am allowed to work with any angular lib

In excel its trivial doing this, but since im fairly new to angular, i'm admittedly a bit lost.

~ Script
var arrayWith5Values = [1,2,3,4,5]
~
    <table>
        <tr>
           <td ng-repeat='numericValue in arrayWith5Values'>
              {{numericValue}}}
           </td>
        </tr>
    </table>

It's basicly the angular version of this question : Coloring HTML table cells from "Low to High Color Shades" depending on Cell Value in Python HTML Email and this Color Cell Based on Value in Cell

I have been searching StackOverflow for the majority of last night and could not find an answer.

Here is an example (screenshot from excel)

Share Improve this question edited May 23, 2017 at 12:26 CommunityBot 11 silver badge asked Apr 10, 2015 at 7:23 Riaan WaltersRiaan Walters 2,6762 gold badges21 silver badges30 bronze badges 8
  • what about 4 and 2? 1 green 3 yellow 5 red for cell color? – huan feng Commented Apr 10, 2015 at 7:27
  • 2 = between yellow and green, its a color range, not hard set colors, if i had 20 values, the color's would be evenly spread from green - red in each cell. – Riaan Walters Commented Apr 10, 2015 at 7:28
  • ok, you just need a dynamic range, like d3 color range – huan feng Commented Apr 10, 2015 at 7:29
  • Yes, but i cant use D3 – Riaan Walters Commented Apr 10, 2015 at 7:30
  • I added a excel example of what i need – Riaan Walters Commented Apr 10, 2015 at 7:31
 |  Show 3 more ments

3 Answers 3

Reset to default 5

Along the same lines of Kirill Slatin's answer, but this one is a lot simpler:

HTML:

<table>
    <tr>
       <td ng-repeat='numericValue in arrayWith5Values' style="background-color: rgb({{getColor($index)}})"
        ng-init="$parent.numValues = arrayWith5Values.length">
          {{numericValue}}
       </td>
    </tr>
 </table>

Controller JS:

$scope.arrayWith5Values = [1,2,3,4,5,6,7,8,9,10];
$scope.getColor = function(index) {
    var greenVal = Math.round(Math.min((255.0*2.0)*(index/($scope.numValues-1)), 255));
    var redVal = Math.round(Math.min((255.0*2.0)*(($scope.numValues-1-index)/($scope.numValues-1))));
    return "" + greenVal + "," + redVal + ",0";
}

Seemed to be working pretty well with the little testing I did. JSFiddle here

Note: this is tailored specifically for green to red. This same math could be applied to other color schemes, but it would have to be somewhat manually done again

Pure Angular and javascript. Javascript code quality is not good, but it is here just for you to get the idea. I was really writing fast...

IDEA: use custom function (getColor()) to define the background color or your elements. Mind that curly braces {{}} in Angular add $watch expressions. So I suggest using once-binding via {{::}} if you have fresh enough Angular (v1.3+). Otherwise use the angular library BindOnce

HTML:

   <tr ng-repeat="arr in data">
        <td ng-repeat="value in arr" ng-attr-style="background: #{{::getColor(value, arr)}};">
            {{value}}
        </td>
    </tr>

Javascript:

$scope.getColor = function(item, array){
    var h = item / array.length ;
    return RGBtoHex(HSVtoRGB(h, 1, 1))
};
function RGBtoHex(color){
    var r = color.r.toString(16);
    if(r.length < 2) r = '0' + r;
    var g = color.g.toString(16);
    if(g.length < 2) g = '0' + g;
    var b = color.b.toString(16);
    if(b.length < 2) b = '0' + b;
    return r + g + b;
}

function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (h && s === undefined && v === undefined) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
    return {
        r: Math.floor(r * 255),
        g: Math.floor(g * 255),
        b: Math.floor(b * 255)
    };

PS: getColor() is function you need to redefine according to you color palette. Mind that Hue in HSV color model changes from 0 to 1 ranging the whole spectrum. You should select which range of the spectrum you would like to achieve from first till last element and accordingly limit in function. Although handle marginal cases (like 1 or 2 elements) based on your specification.

Working example in this jsfiddle

Credits for HSVToRGB() goes for Paul S. https://stackoverflow./a/17243070/4573999

If anyone else stumbled upon this and wasn't as satisfied as I was with the provided solution, I hacked together another solution.

I wanted to be able to use an array of values and color scale them from lowest red to highest green as well as use a midpoint color as yellow.

Take a look below as well as at the fiddle to see a working solution.

ctrl.getColor = function(value, min_value, max_value) {
    let [highMaxR, highMaxG, highMaxB] = [99, 190, 123];
    let [lowMaxR, lowMaxG, lowMaxB] = [248, 105, 107];
    let [midMaxR, midMaxG, midMaxB] = [255, 235, 132];

    if (Math.round(max_value - min_value) === 0) return `${highMaxR}, ${highMaxG}, ${highMaxB}`;

    let mid_point = (max_value + min_value) / 2;
    if (value > mid_point) {
      [lowMaxR, lowMaxG, lowMaxB] = [midMaxR, midMaxG, midMaxB];
      min_value = mid_point;
    } else {
      [highMaxR, highMaxG, highMaxB] = [midMaxR, midMaxG, midMaxB];
      max_value = mid_point;
    }

    let percentage = Math.abs((value - min_value) / (max_value - min_value));

    let redVal = Math.round(lowMaxR + ((highMaxR - lowMaxR) * percentage));
    let greenVal = Math.round(lowMaxG + ((highMaxG - lowMaxG) * percentage));
    let blueVal = Math.round(lowMaxB + ((highMaxB - lowMaxB) * percentage));

    return `${redVal}, ${greenVal}, ${blueVal}`;
};

Here is the fiddle

发布评论

评论列表(0)

  1. 暂无评论