renderer.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import _ from 'lodash';
  3. import moment from 'moment';
  4. import kbn from 'app/core/utils/kbn';
  5. export class TableRenderer {
  6. formaters: any[];
  7. colorState: any;
  8. constructor(private panel, private table, private isUtc, private sanitize) {
  9. this.formaters = [];
  10. this.colorState = {};
  11. }
  12. getColorForValue(value, style) {
  13. if (!style.thresholds) { return null; }
  14. for (var i = style.thresholds.length; i > 0; i--) {
  15. if (value >= style.thresholds[i - 1]) {
  16. return style.colors[i];
  17. }
  18. }
  19. return _.first(style.colors);
  20. }
  21. defaultCellFormater(v, style) {
  22. if (v === null || v === void 0 || v === undefined) {
  23. return '';
  24. }
  25. if (_.isArray(v)) {
  26. v = v.join(', ');
  27. }
  28. if (style && style.sanitize) {
  29. return this.sanitize(v);
  30. } else {
  31. return _.escape(v);
  32. }
  33. }
  34. createColumnFormater(style, column) {
  35. if (!style) {
  36. return this.defaultCellFormater;
  37. }
  38. if (style.type === 'date') {
  39. return v => {
  40. if (v === undefined || v === null) {
  41. return '-';
  42. }
  43. if (_.isArray(v)) { v = v[0]; }
  44. var date = moment(v);
  45. if (this.isUtc) {
  46. date = date.utc();
  47. }
  48. return date.format(style.dateFormat);
  49. };
  50. }
  51. if (style.type === 'number') {
  52. let valueFormater = kbn.valueFormats[column.unit || style.unit];
  53. return v => {
  54. if (v === null || v === void 0) {
  55. return '-';
  56. }
  57. if (_.isString(v)) {
  58. return this.defaultCellFormater(v, style);
  59. }
  60. if (style.colorMode) {
  61. this.colorState[style.colorMode] = this.getColorForValue(v, style);
  62. }
  63. return valueFormater(v, style.decimals, null);
  64. };
  65. }
  66. return (value) => {
  67. return this.defaultCellFormater(value, style);
  68. };
  69. }
  70. formatColumnValue(colIndex, value) {
  71. if (this.formaters[colIndex]) {
  72. return this.formaters[colIndex](value);
  73. }
  74. for (let i = 0; i < this.panel.styles.length; i++) {
  75. let style = this.panel.styles[i];
  76. let column = this.table.columns[colIndex];
  77. var regex = kbn.stringToJsRegex(style.pattern);
  78. if (column.text.match(regex)) {
  79. this.formaters[colIndex] = this.createColumnFormater(style, column);
  80. return this.formaters[colIndex](value);
  81. }
  82. }
  83. this.formaters[colIndex] = this.defaultCellFormater;
  84. return this.formaters[colIndex](value);
  85. }
  86. renderCell(columnIndex, value, addWidthHack = false) {
  87. value = this.formatColumnValue(columnIndex, value);
  88. var style = '';
  89. if (this.colorState.cell) {
  90. style = ' style="background-color:' + this.colorState.cell + ';color: white"';
  91. this.colorState.cell = null;
  92. } else if (this.colorState.value) {
  93. style = ' style="color:' + this.colorState.value + '"';
  94. this.colorState.value = null;
  95. }
  96. // because of the fixed table headers css only solution
  97. // there is an issue if header cell is wider the cell
  98. // this hack adds header content to cell (not visible)
  99. var widthHack = '';
  100. if (addWidthHack) {
  101. widthHack = '<div class="table-panel-width-hack">' + this.table.columns[columnIndex].text + '</div>';
  102. }
  103. return '<td' + style + '>' + value + widthHack + '</td>';
  104. }
  105. render(page) {
  106. let pageSize = this.panel.pageSize || 100;
  107. let startPos = page * pageSize;
  108. let endPos = Math.min(startPos + pageSize, this.table.rows.length);
  109. var html = "";
  110. for (var y = startPos; y < endPos; y++) {
  111. let row = this.table.rows[y];
  112. let cellHtml = '';
  113. let rowStyle = '';
  114. for (var i = 0; i < this.table.columns.length; i++) {
  115. cellHtml += this.renderCell(i, row[i], y === startPos);
  116. }
  117. if (this.colorState.row) {
  118. rowStyle = ' style="background-color:' + this.colorState.row + ';color: white"';
  119. this.colorState.row = null;
  120. }
  121. html += '<tr ' + rowStyle + '>' + cellHtml + '</tr>';
  122. }
  123. return html;
  124. }
  125. render_values() {
  126. let rows = [];
  127. for (var y = 0; y < this.table.rows.length; y++) {
  128. let row = this.table.rows[y];
  129. let new_row = [];
  130. for (var i = 0; i < this.table.columns.length; i++) {
  131. new_row.push(this.formatColumnValue(i, row[i]));
  132. }
  133. rows.push(new_row);
  134. }
  135. return {
  136. columns: this.table.columns,
  137. rows: rows,
  138. };
  139. }
  140. }