Search code examples
javascripthtmlcssrangeconditional-formatting

HTML Table Conditional Cell Color by Value Ranges


I have rendered a HTML file from a Pandas DataFrame which I'm trying to style the cell color based of the cell value. I'm able to do this with the html script below using some JS and CSS:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>DATA FRAME TABLE</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  
 
  <!-- ## WORING HTML -->
  <link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css">
  <link rel="stylesheet" type="text/css" href="vendor/animate/animate.css">
  <link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css">
  <link rel="stylesheet" type="text/css" href="vendor/perfect-scrollbar/perfect-scrollbar.css">
  <link rel="stylesheet" type="text/css" href="css/util.css">
  <link rel="stylesheet" type="text/css" href="css/main.css">

</head>
<body>
<table id="status_report" border="1" class="table table-hover" data-vertable="ver1">
  <tbody  style="text-align: center;">
    <tr>
      <td>Name</td>
      <td>Round 1</td>
      <td>Round 2</td> 
      <td>Round 3</td>
      <td>Round 4</td>
      <td>Avg</td>
    </tr>
    <tr>
      <td>Ben</td>
      <td>19</td>
      <td>24</td>
      <td>22</td>
      <td>27</td>
      <td>23.0</td>
    </tr>
    <tr>
      <td>Harry</td>
      <td>21</td>
      <td>19</td>
      <td>15</td>
      <td>19</td>
      <td>18.5</td>
    </tr>
    <tr>
      <td>Tom</td>
      <td>10</td>
      <td>22</td>
      <td>18</td>
      <td>21</td>
      <td>17.8</td>
    </tr>
    <tr>
      <td>Jack</td>
      <td>18</td>
      <td>19</td>
      <td>16</td>
      <td>17</td>
      <td>17.5</td>
    </tr>
    <tr>
      <td>Angus</td>
      <td>13</td>
      <td>-</td>
      <td>21</td> 
      <td>19</td>
      <td>17.2</td>
    </tr>
  </tbody>
</table>

<script>

  var colorMap = {
      "-": "RGBA(85,83,108,0.4)",
      0 : "RGBA(255,198,191,0.4)",
      1 : "RGBA(255,198,191,0.4)",
      2 : "RGBA(255,198,191,0.4)",
      3 : "RGBA(255,198,191,0.4)",
      4 : "RGBA(255,198,191,0.4)",
      5 : "RGBA(255,198,191,0.4)",
      6 : "RGBA(255,198,191,0.4)",
      7 : "RGBA(255,198,191,0.4)",
      8 : "RGBA(255,198,191,0.4)",
      9 : "RGBA(255,198,191,0.4)",
      10 : "RGBA(255,198,191,0.4)",
      11 : "RGBA(255,198,191,0.4)",
      12 : "RGBA(255,198,191,0.4)",
      13 : "RGBA(255,198,191,0.4)",
      14 : "RGBA(255,198,191,0.4)",
      15 : "RGBA(170,214,136,0.4)",
      16 : "RGBA(170,214,136,0.4)",
      17 : "RGBA(170,214,136,0.4)",
      18 : "RGBA(170,214,136,0.4)",
      19 : "RGBA(170,214,136,0.4)",
      20 : "RGBA(152,195,119,0.6)",
      21 : "RGBA(152,195,119,0.6)",
      22 : "RGBA(152,195,119,0.6)",
      23 : "RGBA(152,195,119,0.6)",
      24 : "RGBA(152,195,119,0.6)",
      25 : "RGBA(139,189,120,0.9)",
      26 : "RGBA(139,189,120,0.9)",
      27 : "RGBA(139,189,120,0.9)",
      28 : "RGBA(139,189,120,0.9)",
      29 : "RGBA(139,189,120,0.9)",
      30 : "RGBA(94,167,88,0.9)",
  };

  $('#status_report td').css('background-color', function(){
      return colorMap[$(this).text()] || '';
  });
</script>

</body>
</html>

However I realise the ColorMap script is very inefficient and not exactly what I'm trying to do. What I really would like to do is have the ColorMap based on ranges - not single integers written out one by one. I have tried doing something similar however using ranges but I'm inexperienced with JS and CSS.

    <script>

      var colorMap = {
          "-": "RGBA(85,83,108,0.4)",
          0-15 : "RGBA(255,198,191,0.4)", # Light Red
          15-20 : "RGBA(170,214,136,0.4)", # Lightest green
          20-25 : "RGBA(152,195,119,0.6)", # Light Green
          25-30 : "RGBA(139,189,120,0.9)", # Dark Green
          30+ : "RGBA(94,167,88,0.9)", # Darkest Green
      };

      $('#status_report td').css('background-color', function(){
          return colorMap[$(this).text()] || '';
      });
    </script>

I know this method doesn't work with the color map, but I want to use ranges to cater for new values being added - for example values higher than 30. It also want it to apply this conditional format to the average columns - so float values in this case.

I feel using a color map may not be the best solution for this. Any suggestions how I can approach this problem?


Solution

  • i think you can setup condition in js like this.

    $(document).ready(function(){
        $('#status_report tr td').each(function(){
            if ($(this).text() == '-') {
                $(this).css('background-color','RGBA(85,83,108,0.4)');
            }else if ($(this).text() >=0 && $(this).text() <=15) {
                $(this).css('background-color','RGBA(255,198,191,0.4)');
            }else if ($(this).text() > 15 && $(this).text() <=20) {
                $(this).css('background-color','RGBA(170,214,136,0.4)');
            }else if ($(this).text() > 20 && $(this).text() <=25) {
                $(this).css('background-color','RGBA(152,195,119,0.6)');
            }else if ($(this).text() > 25 && $(this).text() <=30) {
                $(this).css('background-color','RGBA(139,189,120,0.9)');
            }else if ($(this).text() > 30) {
                $(this).css('background-color','RGBA(94,167,88,0.9)');
            }
        });
    });
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>DATA FRAME TABLE</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    
    </head>
    <body>
    <table id="status_report" border="1" class="table table-hover" data-vertable="ver1">
      <tbody  style="text-align: center;">
        <tr>
          <td>Name</td>
          <td>Round 1</td>
          <td>Round 2</td> 
          <td>Round 3</td>
          <td>Round 4</td>
          <td>Avg</td>
        </tr>
        <tr>
          <td>Ben</td>
          <td>19</td>
          <td>24</td>
          <td>22</td>
          <td>27</td>
          <td>23.0</td>
        </tr>
        <tr>
          <td>Harry</td>
          <td>21</td>
          <td>19</td>
          <td>15</td>
          <td>19</td>
          <td>18.5</td>
        </tr>
        <tr>
          <td>Tom</td>
          <td>10</td>
          <td>22</td>
          <td>18</td>
          <td>21</td>
          <td>17.8</td>
        </tr>
        <tr>
          <td>Jack</td>
          <td>18</td>
          <td>19</td>
          <td>16</td>
          <td>17</td>
          <td>17.5</td>
        </tr>
        <tr>
          <td>Angus</td>
          <td>13</td>
          <td>-</td>
          <td>21</td> 
          <td>19</td>
          <td>17.2</td>
        </tr>
      </tbody>
    </table>
    
    </body>
    </html>