PivotTable.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /* eslint-disable react/sort-prop-types */
  20. import dt from 'datatables.net-bs';
  21. import PropTypes from 'prop-types';
  22. import { formatNumber } from '@superset-ui/number-format';
  23. import fixTableHeight from './utils/fixTableHeight';
  24. import 'datatables.net-bs/css/dataTables.bootstrap.css';
  25. if (window.$) {
  26. dt(window, window.$);
  27. }
  28. const $ = window.$ || dt.$;
  29. const propTypes = {
  30. data: PropTypes.shape({
  31. // TODO: replace this with raw data in SIP-6
  32. html: PropTypes.string,
  33. columns: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]))
  34. }),
  35. height: PropTypes.number,
  36. columnFormats: PropTypes.objectOf(PropTypes.string),
  37. numberFormat: PropTypes.string,
  38. numGroups: PropTypes.number,
  39. verboseMap: PropTypes.objectOf(PropTypes.string)
  40. };
  41. function PivotTable(element, props) {
  42. const {
  43. data,
  44. height,
  45. columnFormats,
  46. numberFormat,
  47. numGroups,
  48. verboseMap
  49. } = props;
  50. const {
  51. html,
  52. columns
  53. } = data;
  54. const container = element;
  55. const $container = $(element); // queryData data is a string of html with a single table element
  56. container.innerHTML = html;
  57. const cols = Array.isArray(columns[0]) ? columns.map(col => col[0]) : columns; // jQuery hack to set verbose names in headers
  58. // eslint-disable-next-line func-name-matching
  59. const replaceCell = function replace() {
  60. const s = $(this)[0].textContent;
  61. $(this)[0].textContent = verboseMap[s] || s;
  62. };
  63. $container.find('thead tr:first th').each(replaceCell);
  64. $container.find('thead tr th:first-child').each(replaceCell); // jQuery hack to format number
  65. $container.find('tbody tr').each(function eachRow() {
  66. $(this).find('td').each(function each(i) {
  67. const metric = cols[i];
  68. const format = columnFormats[metric] || numberFormat || '.3s';
  69. const tdText = $(this)[0].textContent;
  70. if (!Number.isNaN(tdText) && tdText !== '' && tdText.trim().toLowerCase() !== 'null') {
  71. $(this)[0].textContent = formatNumber(format, tdText);
  72. $(this).attr('data-sort', tdText);
  73. }
  74. });
  75. });
  76. if (numGroups === 1) {
  77. // When there is only 1 group by column,
  78. // we use the DataTable plugin to make the header fixed.
  79. // The plugin takes care of the scrolling so we don't need
  80. // overflow: 'auto' on the table.
  81. container.style.overflow = 'hidden';
  82. const table = $container.find('table').DataTable({
  83. paging: false,
  84. searching: false,
  85. bInfo: false,
  86. scrollY: height + "px",
  87. scrollCollapse: true,
  88. scrollX: true
  89. });
  90. table.column('-1').order('desc').draw();
  91. fixTableHeight($container.find('.dataTables_wrapper'), height);
  92. } else {
  93. // When there is more than 1 group by column we just render the table, without using
  94. // the DataTable plugin, so we need to handle the scrolling ourselves.
  95. // In this case the header is not fixed.
  96. container.style.overflow = 'auto';
  97. container.style.height = height + 10 + "px";
  98. }
  99. }
  100. PivotTable.displayName = 'PivotTable';
  101. PivotTable.propTypes = propTypes;
  102. export default PivotTable;