2016-03-18 02:44:58 -04:00
|
|
|
var $ = window.$ = require('jquery');
|
|
|
|
var jQuery = window.jQuery = $;
|
|
|
|
var d3 = require('d3');
|
2016-05-10 12:22:32 -04:00
|
|
|
var px = window.px || require('../javascripts/modules/caravel.js');
|
2016-03-18 02:44:58 -04:00
|
|
|
|
|
|
|
require('./table.css');
|
2016-04-04 19:12:28 -04:00
|
|
|
require('datatables.net-bs');
|
2016-03-18 02:44:58 -04:00
|
|
|
require('../node_modules/datatables-bootstrap3-plugin/media/css/datatables-bootstrap3.css');
|
2016-06-22 19:16:27 -04:00
|
|
|
var utils = require('../javascripts/modules/utils');
|
2016-03-18 02:44:58 -04:00
|
|
|
|
|
|
|
function tableVis(slice) {
|
|
|
|
var f = d3.format('.3s');
|
|
|
|
var fC = d3.format('0,000');
|
2016-05-10 12:22:32 -04:00
|
|
|
var timestampFormatter;
|
2016-03-18 02:44:58 -04:00
|
|
|
|
|
|
|
function refresh() {
|
|
|
|
$.getJSON(slice.jsonEndpoint(), onSuccess).fail(onError);
|
|
|
|
|
|
|
|
function onError(xhr) {
|
2016-06-21 12:42:44 -04:00
|
|
|
slice.error(xhr.responseText, xhr);
|
2016-03-18 02:44:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function onSuccess(json) {
|
|
|
|
var data = json.data;
|
2016-05-10 14:49:32 -04:00
|
|
|
var form_data = json.form_data;
|
2016-03-18 02:44:58 -04:00
|
|
|
var metrics = json.form_data.metrics;
|
|
|
|
|
|
|
|
function col(c) {
|
|
|
|
var arr = [];
|
|
|
|
for (var i = 0; i < data.records.length; i++) {
|
2016-05-10 14:49:32 -04:00
|
|
|
arr.push(data.records[i][c]);
|
2016-03-18 02:44:58 -04:00
|
|
|
}
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
var maxes = {};
|
|
|
|
for (var i = 0; i < metrics.length; i++) {
|
|
|
|
maxes[metrics[i]] = d3.max(col(metrics[i]));
|
|
|
|
}
|
|
|
|
|
2016-05-10 12:22:32 -04:00
|
|
|
if (json.form_data.table_timestamp_format === 'smart_date') {
|
|
|
|
timestampFormatter = px.formatDate;
|
|
|
|
} else if (json.form_data.table_timestamp_format !== undefined) {
|
|
|
|
timestampFormatter = px.timeFormatFactory(json.form_data.table_timestamp_format);
|
|
|
|
}
|
|
|
|
|
2016-05-10 14:49:32 -04:00
|
|
|
var div = d3.select(slice.selector);
|
|
|
|
div.html('');
|
|
|
|
var table = div.append('table')
|
2016-03-18 11:52:50 -04:00
|
|
|
.classed('dataframe dataframe table table-striped table-bordered table-condensed table-hover dataTable no-footer', true)
|
|
|
|
.attr('width', '100%');
|
2016-03-18 02:44:58 -04:00
|
|
|
|
|
|
|
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(function (row, i) {
|
|
|
|
return data.columns.map(function (c) {
|
2016-05-10 12:22:32 -04:00
|
|
|
var val = row[c];
|
|
|
|
if (c === 'timestamp') {
|
|
|
|
val = timestampFormatter(val);
|
|
|
|
}
|
2016-03-18 02:44:58 -04:00
|
|
|
return {
|
|
|
|
col: c,
|
2016-05-10 12:22:32 -04:00
|
|
|
val: val,
|
2016-03-18 02:44:58 -04:00
|
|
|
isMetric: metrics.indexOf(c) >= 0
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}).enter()
|
|
|
|
.append('td')
|
|
|
|
.style('background-image', function (d) {
|
|
|
|
if (d.isMetric) {
|
|
|
|
var perc = Math.round((d.val / maxes[d.col]) * 100);
|
|
|
|
return "linear-gradient(to right, lightgrey, lightgrey " + perc + "%, rgba(0,0,0,0) " + perc + "%";
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.attr('title', function (d) {
|
|
|
|
if (!isNaN(d.val)) {
|
|
|
|
return fC(d.val);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.attr('data-sort', function (d) {
|
|
|
|
if (d.isMetric) {
|
|
|
|
return d.val;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.on("click", function (d) {
|
|
|
|
if (!d.isMetric) {
|
|
|
|
var 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) {
|
|
|
|
if (!d.isMetric) {
|
|
|
|
return 'pointer';
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.html(function (d) {
|
|
|
|
if (d.isMetric) {
|
|
|
|
return f(d.val);
|
|
|
|
} else {
|
|
|
|
return d.val;
|
|
|
|
}
|
|
|
|
});
|
2016-06-22 19:16:27 -04:00
|
|
|
var height = slice.container.height();
|
2016-03-18 02:44:58 -04:00
|
|
|
var datatable = slice.container.find('.dataTable').DataTable({
|
|
|
|
paging: false,
|
2016-04-11 15:11:47 -04:00
|
|
|
searching: form_data.include_search,
|
2016-06-22 19:16:27 -04:00
|
|
|
bInfo: false,
|
|
|
|
scrollY: height + "px",
|
|
|
|
scrollCollapse: true,
|
|
|
|
scrollX: true
|
2016-03-18 02:44:58 -04:00
|
|
|
});
|
2016-06-22 19:16:27 -04:00
|
|
|
utils.fixDataTableBodyHeight(
|
|
|
|
slice.container.find('.dataTables_wrapper'), height);
|
2016-03-18 02:44:58 -04:00
|
|
|
// Sorting table by main column
|
|
|
|
if (form_data.metrics.length > 0) {
|
|
|
|
var main_metric = form_data.metrics[0];
|
|
|
|
datatable.column(data.columns.indexOf(main_metric)).order('desc').draw();
|
|
|
|
}
|
|
|
|
slice.done(json);
|
|
|
|
slice.container.parents('.widget').find('.tooltip').remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
render: refresh,
|
|
|
|
resize: function () {}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-05-10 14:49:32 -04:00
|
|
|
module.exports = tableVis;
|