2012-02-13 26 views
2

对于具有数字的HTML表格,我正在寻找一种优雅的JavaScript/CSS方法来识别每列中等值的组,并相应地为相应单元格的背景着色。我将在回归测试结果的网络演示中使用它。如何为相同元素的表单元组着色

在python中,我可能会使用类似itertools.groupby()的东西。

为了说明,我包含了一个屏幕截图示例和相应的HTML代码(手动构建)。

<head> 
    <style> 
    td {font-family: Monospace; font-size:16; } 
    </style> 
</head> 

<body> 
    <table border=1> 
    <tr><td>1.111</td></tr> 
    <tr><td>1.111</td></tr> 
    <tr><td bgcolor="LightBlue">2.222</td></tr> 
    <tr><td>1.111</td></tr> 
    <tr><td bgcolor="LightBlue">2.222</td></tr> 
    <tr><td> 1.111</td></tr> 
    <tr><td bgcolor="LightBlue">2.222</td></tr> 
    <tr><td bgcolor="Goldenrod">3.333</td></tr> 
    <tr><td> 1.111</td></tr> 
    </table> 
</body> 

enter image description here

+3

你有没有试过自己?你在使用图书馆还是在编写香草JavaScript? – 2012-02-13 13:16:33

+0

你打算使用jQuery吗? – 2012-02-13 13:16:51

+0

最初我想象写我自己的小JavaScript函数......我不熟悉jQuery。如果它提供了一些简单的东西,我可能会说服它来使用它? – user1069609 2012-02-13 13:23:15

回答

0

这里是一个纯JavaScript解决方案(与jsFiddle)您发布样本来源的作品:

function colorTableCells() { 
    'use strict'; 
    var i = 0; //counter variable 
    var j = 0; //counter variable 
    var k = 0; //counter variable 
    var m = 0; //counter variable 
    var n = 0; //counter variable 
    var tables = document.getElementsByTagName('table'); //All tables as a collection. 
    var rows = []; //table rows collection, needed to determine columns 
    var cells = []; //td collection 
    var cell = {}; //used first as a Cell object (custom, see below) and then as a td (after all unique values by column have been determined 
    var values = []; //array of Cell objects (custom, see below). 
    var columnColorMap = { 
     'column0': 'gray', 
     'column1': 'purple', 
     'column2': 'pink', 
     'column3': 'mint', 
     'column4': 'cyan' 
    }; //columnColorMap holds the shade with which to color the column. 
    var C = function() { 
     //Cell Object, holds properties unique to the cells for coloring 
     this.value = 0; //Cell value 
     this.color = { 
      'red': 255, 
      'green': 255, 
      'blue': 255 
     }; //Cell color, determined by column 
     this.shades = { 
      'gray': [this.color.red, this.color.green, this.color.blue], 
      'purple': [this.color.red, this.color.green], 
      'pink': [null, this.color.green, this.color.blue], 
      'mint': [this.color.red, , this.color.blue], 
      'cyan': [this.color.red], 
      'magenta': [null, this.color.green], 
      'yellow': [null, null, this.color.blue] 
     }; //A quick way to determine the shade for the column. It holds color values to modify (and always in RGB order) or a null value if R, G, or B should be left alone. 
     this.column = 0; //Column the cell is in, relative to the table it is in. 
     this.darken = function (stepValue, hue) { 
      //function that returns a new color, based on the hue that is passed in 
      var decrement = 8; 
      var i = 0; 
      var ret = { 
       'red': 255, 
       'green': 255, 
       'blue': 255 
      }; 
      if (!stepValue) { 
       stepValue = 0; 
      } 
      decrement = decrement * stepValue; 
      for (i = 0; i < hue.length; i += 1) { 
       if (hue[i]) { 
        hue[i] = hue[i] - decrement; 
       } 
      } 
      if (hue[0]) { 
       ret.red = hue[0]; 
      } 
      if (hue[1]) { 
       ret.green = hue[1]; 
      } 
      if (hue[2]) { 
       ret.blue = hue[2]; 
      } 
      return ret; 
     }; 
     this.getHexBackgroundColorString = function() { 
      //returns `rbg(val, val, val) as '#RRGGBB' 
      var s = ''; 
      var red = this.color.red.toString(16); 
      var green = this.color.green.toString(16); 
      var blue = this.color.blue.toString(16); 
      if (red.length < 2) { 
       red = '0' + red; 
      } 
      if (green.length < 2) { 
       green = '0' + green; 
      } 
      if (green.length < 2) { 
       blue = '0' + blue; 
      } 
      s = '#' + red + green + blue; 
      return s.toUpperCase(); 
     }; 
    }; 
    var colHasValue = function (array, cell) { 
     //loop through array, returns 'if cell.value && cell.column are found or otherwise' 
     var i = 0; 
     var found = false; 
     for (i = 0; i < array.length; i += 1) { 
      if (array[i].value === cell.value && array[i].column === cell.column) { 
       found = true; 
       i = array.length; 
      } 
     } 
     return found; 
    }; 
    for (i = 0; i < tables.length; i += 1) { 
     cells = tables[i].getElementsByTagName('td'); //get all td elements per table 
     for (j = 0; j < cells.length; j += 1) { 
      cell = new C(); //grab a new Cell object 
      cell.value = parseFloat(cells[j].innerText); //capture cell value 
      cell.column = cells[j].cellIndex; //capture cell column 
      if (!colHasValue(values, cell)) { 
       //hasn't been previously stored yet, so darken according to column and store 
       cell.color = cell.darken(j, cell.shades[columnColorMap['column' + cell.column.toString()]]); 
       values.push(cell); //capture all unique values 
      } 
     } 
     rows = tables[i].getElementsByTagName('tr'); //grab all rows by table 
     for (k = 0; k < rows.length; k += 1) { 
      //start looping through all the rows 
      for (m = 0; m < rows[k].childNodes.length; m += 1) { 
       //start looping through all of the row's children 
       if (rows[k].childNodes[m].nodeName.toLowerCase() === 'td') { 
        cell = rows[k].childNodes[m]; //found a td element, alias to cell for easier use 
        for (n = 0; n < values.length; n += 1) { 
         //loop through stored cell values 
         if (parseFloat(cell.innerText) === values[n].value && cell.cellIndex === values[n].column) { 
          //value and column matches 
          cell.style.backgroundColor = values[n].getHexBackgroundColorString(); //set background-color 
          n = values.length; //exit for 
         } 
        } 
       } 
      } 
     } 
    } 
} 
colorTableCells(); 

修改的任何(或全部)下面,以改变颜色:

  • shades收藏
  • columnColorMap物体
  • darken功能
+0

谢谢,这非常有趣。就像我上面提到的jAndy一样,在我的初始文章中可能还不够清楚,我需要将平等的范围限制为与其余部分隔离的每个列,而不是整个表。我的意思是在一列中只有相同的值**应具有相同的背景颜色。我怎样才能用你的模型做到这一点? – user1069609 2012-02-13 15:43:01

+0

好的,修改为通过列工作而不是任意表数据。此外,评论来源,更多地着色,摆弄更新jsFiddle。更新后的新源和jsFiddle。 – pete 2012-02-14 13:08:11

0

你可以使用jQuery,

$("td:contains('2.222')").css("background-color","LightBlue"); 
$("td:contains('3.333')").css("background-color","Goldenrod"); 
1

我能想到的是这样的

var lookup = Object.create(null); 

Array.prototype.forEach.call(document.querySelectorAll('table td'), function(td) { 
    var id = td.textContent.trim(); 

    if(typeof lookup[ id ] === 'undefined') { 
     lookup[ id ] = [ td ]; 
    } 
    else { 
     lookup[ id ].push(td); 
    } 
}); 

Object.keys(lookup).forEach(function(name) { 
    if(lookup[ name ] && lookup[ name ].length) { 
     var rnd = 'rgba(red,green,blue,1)' 
      .replace('red', ~~(Math.random() * 255)) 
      .replace('green', ~~(Math.random() * 255)) 
      .replace('blue', ~~(Math.random() * 255)); 

     lookup[ name ].forEach(function(td) { 
      td.style.backgroundColor = rnd; 
     }); 
    } 
}); 

演示:http://jsfiddle.net/ch6qZ/1/

谨慎的新词:上面的代码在很大程度上依赖于ES5,所以如果你想使用它确保你也已经装入了一个ES5,沉图书馆网站上的老'ish浏览器。此外,querySelectorAll的选择器应该更具体,最好的情况下,你可以给该表一个ID。最后在本例中按照Math.random()发生颜色生成,您可能需要自行定义颜色。


此示例代码创建一个空对象并将其用作散列。可用的td值作为键名创建一次,每个键的值是共享相同文本内容的td的数组。在完成之后,我们遍历该散列并为每个td -group设置一个随机背景色。

+0

谢谢,这非常有趣。在我的初始文章中,我可能并不清楚,但在我的情况下,我需要将平等的范围限制为与其余部分隔离的每个列,而不是整个表。我的意思是在一列中只有相同的值**应具有相同的背景颜色。我不确定如何用你的模型做到这一点? – user1069609 2012-02-13 15:41:39

+0

@ user1069609:我不完全确定你的意思,但是你可以修改'querySelectorAll'选择器来只选择某些列。对于实例'table td:nth-​​child(1)'只会影响第一列 – jAndy 2012-02-13 16:21:05

+0

如何循环使用给定ID的表的所有列? 还有一个更一般的问题:您能否指出我对您提供的JavaScript类型的很好的参考? – user1069609 2012-02-14 10:59:18

相关问题