2012-02-13 4 views
2

数値を含むHTMLテーブルの場合、各列の等しい値のグループを識別し、それに応じて対応するセルの背景を色付けするための洗練されたJavaScript/CSS方法を探しています。私は回帰テスト結果のWebプレゼンテーションでそれを使用します。等価要素のテーブルセルグループの色付け方法

私はおそらく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を書いていますか? –

+0

jQueryを使用していますか? –

+0

最初は私自身の小さなJavaScript関数を書こうと思っていました...私はjQueryに慣れていません。私はおそらくそれが何か簡単なものを提供すればそれを使うように説得することができますか? – user1069609

答えて

0

は、あなたの投稿のサンプルソースに取り組んでいます(jsFiddle付き)純粋なJavaScriptのソリューションです:

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

+0

これは、任意のテーブルデータではなく、カラムを介して動作するように修正されました。また、ソースにコメントし、色付けしてより多くを手に入れ、更新されたjsFiddleを投稿しました。新しいソースとjsFiddleでポストを更新しました。 – pete

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のセレクタは、より具体的な最善のケースのシナリオである必要があります。最後に、この例ではMath.random()で色が生成されますが、独自に色を定義することもできます。


このサンプルコードでは、空のオブジェクトを作成し、ハッシュとして使用します。使用可能なtdの値はkeynameとして1回作成され、各キーの値は同じテキスト内容を共有するtdの配列です。それが終わると、そのハッシュをループし、td -groupごとにランダムな背景色を設定します。ここで

+0

ありがとう、これは非常に興味深いです。おそらく私の最初の投稿ではっきりしていなかったかもしれませんが、私の場合、テーブル全体ではなく、残りの列から分離された各列に平等の範囲を限定する必要があります。私は、同じ列の**内の等しい値**は、同じ背景色を持つ必要があることを意味します。あなたのモデルでそれをどうやって行うのか分かりません。 – user1069609

+0

@ user1069609:どういう意味なのかよく分かりませんが、 'querySelectorAll'セレクタを変更して特定の列だけを選択することができます。 'テーブルtd:nth-​​child(1)'は最初のカラムにのみ影響します – jAndy

+0

与えられたIDを持つテーブルのすべてのカラムをどのようにループできますか? より一般的な質問:あなたが提供した種類のJavaScriptについての良いリファレンスを教えてもらえますか? – user1069609

関連する問題