diff --git a/src/d3loader.js b/src/d3loader.js index e32711f..ed824ba 100644 --- a/src/d3loader.js +++ b/src/d3loader.js @@ -3,5 +3,6 @@ import {select, selectAll, event} from 'd3-selection'; import {transition} from 'd3-transition'; import {drag} from 'd3-drag'; +import {ascending, descending} from 'd3-array'; -export {select, selectAll, event, transition, drag}; +export {select, selectAll, event, transition, drag, ascending, descending}; diff --git a/src/report_table.js b/src/report_table.js index 35e5cf8..92463b9 100644 --- a/src/report_table.js +++ b/src/report_table.js @@ -14,6 +14,9 @@ const BBOX_X_ADJUST = 10; const BBOX_Y_ADJUST = 10; const use_minicharts = false; +let sortOrder = false; +let columnKey = ''; +let pivotKey = ''; const removeStyles = async function () { const links = document.getElementsByTagName('link'); @@ -35,7 +38,8 @@ const buildReportTable = function ( config, dataTable, updateColumnOrder, - element + element, + updateSorting ) { var dropTarget = null; const bounds = element.getBoundingClientRect(); @@ -194,6 +198,7 @@ const buildReportTable = function ( return ''; } }); + var header_rows = table .append('thead') .selectAll('tr') @@ -228,17 +233,25 @@ const buildReportTable = function ( .style('font-size', config.headerFontSize + 'px') .attr('draggable', true) .call(drag) - .on('mouseover', function(cell) { + .on('mouseover', function (cell) { d3.select('#tooltip') - .style('left', d3.event.x + 'px') - .style('top', d3.event.y + 'px') - .html(cell.label); + .style('left', d3.event.x + 'px') + .style('top', d3.event.y + 'px') + .html(cell.label); d3.select('#tooltip').classed('hidden', false); - return dropTarget = cell + return (dropTarget = cell); }) - .on('mouseout', function(cell) { + .on('mouseout', function (cell) { d3.select('#tooltip').classed('hidden', true); - return dropTarget = null + return (dropTarget = null); + }) + .on('click', function (cell) { + if (!dataTable.transposeTable) { + let column_key = cell.column.modelField.name; + let pivot_key = cell.column.pivot_key; + updateSorting(sortOrder, column_key, pivot_key); + sortOrder = !sortOrder; + } }); var table_rows = table @@ -376,7 +389,7 @@ const buildReportTable = function ( // Looker applies padding based on the top of the viz when opening a drill field but // if part of the viz container is hidden underneath the iframe, the drill menu opens off screen // We make a simple copy of the d3.event and account for pageYOffser as MouseEvent attributes are read only. - if (d.links !== [] && d.links[0].url) { + if (Array.isArray(d.links) && d.links.length !== 0 && d.links[0].url) { let event = { metaKey: d3.event.metaKey, pageX: d3.event.pageX, @@ -631,6 +644,37 @@ looker.plugins.visualizations.add({ ); } + // Here goes the sorting then the vis is built again + // If order = true => ascending + // If order = false => descending + const updateSorting = (order, key, pivot) => { + columnKey = key; + pivotKey = pivot; + this.trigger('updateConfig', [ + {sorting: order ? 'ascending' : 'descending'}, + ]); + }; + + if (columnKey !== '') { + if (config.sorting === 'ascending') { + data.sort((a, b) => { + const value_1 = + pivotKey === '' ? a[columnKey].value : a[columnKey][pivotKey].value; + const value_2 = + pivotKey === '' ? b[columnKey].value : b[columnKey][pivotKey].value; + return d3.ascending(value_1, value_2); + }); + } else if (config.sorting === 'descending') { + data.sort((a, b) => { + const value_1 = + pivotKey === '' ? a[columnKey].value : a[columnKey][pivotKey].value; + const value_2 = + pivotKey === '' ? b[columnKey].value : b[columnKey][pivotKey].value; + return d3.descending(value_1, value_2); + }); + } + } + // BUILD THE VIS // 1. Create object // 2. Register options @@ -639,7 +683,13 @@ looker.plugins.visualizations.add({ // console.log(config) var dataTable = new VisPluginTableModel(data, queryResponse, config); this.trigger('registerOptions', dataTable.getConfigOptions()); - buildReportTable(config, dataTable, updateColumnOrder, element); + buildReportTable( + config, + dataTable, + updateColumnOrder, + element, + updateSorting + ); // DEBUG OUTPUT AND DONE // console.log('dataTable', dataTable) diff --git a/src/vis_table_plugin.js b/src/vis_table_plugin.js index f671df3..507d18c 100644 --- a/src/vis_table_plugin.js +++ b/src/vis_table_plugin.js @@ -190,6 +190,10 @@ const tableModelCoreOptions = { default: false, order: 100, }, + sorting: { + type: 'string', + default: 'ascending', + }, }; /** * Represents an "enriched data object" with additional methods and properties for data vis diff --git a/webpack.config.js b/webpack.config.js index cab8874..77c1f9b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,7 @@ const path = require('path'); module.exports = { + mode: 'development', entry: './src/report_table.js', output: { filename: 'bundle.js', @@ -12,7 +13,7 @@ module.exports = { { test: /\.css$/i, use: [ - { loader: 'style-loader', options: { injectType: 'lazyStyleTag' } }, + {loader: 'style-loader', options: {injectType: 'lazyStyleTag'}}, 'css-loader', ], },