Files
superset2/superset/assets/visualizations/table.js
Maxime Beauchemin 0cc8eff1c3 [WiP] Deprecate Explore v1 (#2064)
* Simplifying the viz interface (#2005)

* Working on dashes

* Making this a collaborative branch

* Fixing some bugs

* Fixing bugs

* More improvements

* Add datasource back in bootstrap data

* Decent state

* Linting

* Moving forward

* Some more linting

* Fix the timer

* Triggering events through state

* Lingint

* Put filters in an array instead of flt strings (#2090)

* Put filters in an array instead of flt strings

* Remove query_filter(), put opChoices into Filter

* Update version_info.json

* Fix migrations

* More renderTrigger=true

* Fixing bugs

* Working on standalone

* getting standalone to work

* Fixed forcedHeight for standalone =view

* Linting

* Get save slice working in v2 (#2106)

* Filter bugfix

* Fixing empty series limit bug

* Fixed dashboard view

* Fixing short urls

* Only allow owners to overwrite slice (#2142)

* Raise exception when date range is wrong

* Only allow owner to overwrite a slice

* Fix tests for deprecate v1 (#2140)

* Fixed tests for control panels container and filters

* Fixed python tests for explorev2

* Fix linting errors

* Add in stop button during slice querying/rendering (#2121)

* Add in stop button during slice querying/rendering

* Abort ajax request on stop

* Adding missing legacy module

* Removing select2.sortable.js because of license

* Allow query to display while slice is loading (#2100)

* Allow query to display while slice is loading

* Put latestQueryFormData in store

* Reorganized query function, got rid of tu[le return values

* Merging migrations

* Wrapping up shortner migration

* Fixing tests

* Add folder creation to syncBackend

* Fixing edit URL in explore view

* Fix look of Stop button

* Adding syntax highlighting to query modal

* Fix cast_form_data and flase checkbox on dash

* Bugfix

* Going deeper

* Fix filtering

* Deleing invalid filters when changing datasource

* Minor adjustments

* Fixing calendar heatmap examples

* Moving edit datasource button to header's right side

* Fixing mapbox example

* Show stack trace when clicking alert

* Adding npm sync-backend command to build instruction

* Bumping up JS dependencies

* rm dep on select2

* Fix py3 urlparse

* rm superset-select2.js

* Improving migration scripts

* Bugfixes on staging

* Fixing Markup viz
2017-02-16 17:28:35 -08:00

154 lines
4.0 KiB
JavaScript

import d3 from 'd3';
import { fixDataTableBodyHeight } from '../javascripts/modules/utils';
import { timeFormatFactory, formatDate } from '../javascripts/modules/dates';
require('./table.css');
const $ = require('jquery');
require('datatables-bootstrap3-plugin/media/css/datatables-bootstrap3.css');
import 'datatables.net';
import dt from 'datatables.net-bs';
dt(window, $);
function tableVis(slice, payload) {
const container = $(slice.selector);
const fC = d3.format('0,000');
let timestampFormatter;
const data = payload.data;
const fd = slice.formData;
// Removing metrics (aggregates) that are strings
const realMetrics = [];
for (const k in data.records[0]) {
if (fd.metrics.indexOf(k) > -1 && !isNaN(data.records[0][k])) {
realMetrics.push(k);
}
}
const metrics = realMetrics;
function col(c) {
const arr = [];
for (let i = 0; i < data.records.length; i++) {
arr.push(data.records[i][c]);
}
return arr;
}
const maxes = {};
for (let i = 0; i < metrics.length; i++) {
maxes[metrics[i]] = d3.max(col(metrics[i]));
}
if (fd.table_timestamp_format === 'smart_date') {
timestampFormatter = formatDate;
} else if (fd.table_timestamp_format !== undefined) {
timestampFormatter = timeFormatFactory(fd.table_timestamp_format);
}
const div = d3.select(slice.selector);
div.html('');
const table = div.append('table')
.classed(
'dataframe dataframe table table-striped table-bordered ' +
'table-condensed table-hover dataTable no-footer', true)
.attr('width', '100%');
table.append('thead').append('tr')
.selectAll('th')
.data(data.columns)
.enter()
.append('th')
.text(function (d) {
return d;
});
table.append('tbody')
.selectAll('tr')
.data(data.records)
.enter()
.append('tr')
.selectAll('td')
.data((row) => data.columns.map((c) => {
let val = row[c];
if (c === 'timestamp') {
val = timestampFormatter(val);
}
if (typeof(val) === 'string') {
val = `<span class="like-pre">${val}</span>`;
}
return {
col: c,
val,
isMetric: metrics.indexOf(c) >= 0,
};
}))
.enter()
.append('td')
.style('background-image', function (d) {
if (d.isMetric) {
const perc = Math.round((d.val / maxes[d.col]) * 100);
return (
`linear-gradient(to right, lightgrey, lightgrey ${perc}%, ` +
`rgba(0,0,0,0) ${perc}%`
);
}
return null;
})
.attr('title', (d) => {
if (!isNaN(d.val)) {
return fC(d.val);
}
return null;
})
.attr('data-sort', function (d) {
return (d.isMetric) ? d.val : null;
})
.on('click', function (d) {
if (!d.isMetric && fd.table_filter) {
const td = d3.select(this);
if (td.classed('filtered')) {
slice.removeFilter(d.col, [d.val]);
d3.select(this).classed('filtered', false);
} else {
d3.select(this).classed('filtered', true);
slice.addFilter(d.col, [d.val]);
}
}
})
.style('cursor', function (d) {
return (!d.isMetric) ? 'pointer' : '';
})
.html((d) => {
if (d.isMetric) {
return slice.d3format(d.col, d.val);
}
return d.val;
});
const height = slice.height();
let paging = false;
let pageLength;
if (fd.page_length && fd.page_length > 0) {
paging = true;
pageLength = parseInt(fd.page_length, 10);
}
const datatable = container.find('.dataTable').DataTable({
paging,
pageLength,
aaSorting: [],
searching: fd.include_search,
bInfo: false,
scrollY: height + 'px',
scrollCollapse: true,
scrollX: true,
});
fixDataTableBodyHeight(
container.find('.dataTables_wrapper'), height);
// Sorting table by main column
if (fd.metrics.length > 0) {
const mainMetric = fd.metrics[0];
datatable.column(data.columns.indexOf(mainMetric)).order('desc').draw();
}
container.parents('.widget').find('.tooltip').remove();
}
module.exports = tableVis;