From da52d03bbec6312774d233cb062df5125fc1a151 Mon Sep 17 00:00:00 2001 From: Jun Tan Date: Tue, 9 Apr 2019 23:00:35 -0500 Subject: [PATCH] skip header rows for column-only --- cpp/perspective/src/cpp/data_slice.cpp | 16 ++++--- cpp/perspective/src/cpp/view.cpp | 22 +++++++--- .../src/include/perspective/data_slice.h | 6 ++- .../src/include/perspective/view.h | 2 + packages/perspective/src/js/perspective.js | 8 ++-- packages/perspective/test/js/to_format.js | 42 ++++++++++++++++++- 6 files changed, 77 insertions(+), 19 deletions(-) diff --git a/cpp/perspective/src/cpp/data_slice.cpp b/cpp/perspective/src/cpp/data_slice.cpp index 6d729f6966..a3db624540 100644 --- a/cpp/perspective/src/cpp/data_slice.cpp +++ b/cpp/perspective/src/cpp/data_slice.cpp @@ -14,13 +14,16 @@ namespace perspective { template t_data_slice::t_data_slice(std::shared_ptr ctx, t_uindex start_row, - t_uindex end_row, t_uindex start_col, t_uindex end_col, - const std::shared_ptr>& slice, std::vector column_names) + t_uindex end_row, t_uindex start_col, t_uindex end_col, t_uindex row_offset, + t_uindex col_offset, const std::shared_ptr>& slice, + std::vector column_names) : m_ctx(ctx) , m_start_row(start_row) , m_end_row(end_row) , m_start_col(start_col) , m_end_col(end_col) + , m_row_offset(row_offset) + , m_col_offset(col_offset) , m_slice(slice) , m_column_names(column_names) { m_stride = m_end_col - m_start_col; @@ -28,14 +31,16 @@ t_data_slice::t_data_slice(std::shared_ptr ctx, t_uindex start_row template t_data_slice::t_data_slice(std::shared_ptr ctx, t_uindex start_row, - t_uindex end_row, t_uindex start_col, t_uindex end_col, - const std::shared_ptr>& slice, std::vector column_names, - std::vector column_indices) + t_uindex end_row, t_uindex start_col, t_uindex end_col, t_uindex row_offset, + t_uindex col_offset, const std::shared_ptr>& slice, + std::vector column_names, std::vector column_indices) : m_ctx(ctx) , m_start_row(start_row) , m_end_row(end_row) , m_start_col(start_col) , m_end_col(end_col) + , m_row_offset(row_offset) + , m_col_offset(col_offset) , m_slice(slice) , m_column_names(column_names) , m_column_indices(column_indices) { @@ -49,6 +54,7 @@ t_data_slice::~t_data_slice() {} template t_tscalar t_data_slice::get(t_uindex ridx, t_uindex cidx) const { + ridx += m_row_offset; t_uindex idx = get_slice_idx(ridx, cidx); t_tscalar rv; if (idx >= m_slice->size()) { diff --git a/cpp/perspective/src/cpp/view.cpp b/cpp/perspective/src/cpp/view.cpp index 8e0b7dd954..0afe9bb6b9 100644 --- a/cpp/perspective/src/cpp/view.cpp +++ b/cpp/perspective/src/cpp/view.cpp @@ -20,6 +20,7 @@ View::View(t_pool* pool, std::shared_ptr ctx, std::shared_ptr::View(t_pool* pool, std::shared_ptr ctx, std::shared_ptr @@ -230,8 +234,8 @@ View::get_data( auto slice_ptr = std::make_shared>( m_ctx->get_data(start_row, end_row, start_col, end_col)); auto col_names = _column_names(); - auto data_slice_ptr = std::make_shared>( - m_ctx, start_row, end_row, start_col, end_col, slice_ptr, col_names); + auto data_slice_ptr = std::make_shared>(m_ctx, start_row, end_row, + start_col, end_col, m_row_offset, m_col_offset, slice_ptr, col_names); return data_slice_ptr; } @@ -243,8 +247,8 @@ View::get_data( m_ctx->get_data(start_row, end_row, start_col, end_col)); auto col_names = _column_names(); col_names.insert(col_names.begin(), "__ROW_PATH__"); - auto data_slice_ptr = std::make_shared>( - m_ctx, start_row, end_row, start_col, end_col, slice_ptr, col_names); + auto data_slice_ptr = std::make_shared>(m_ctx, start_row, end_row, + start_col, end_col, m_row_offset, m_col_offset, slice_ptr, col_names); return data_slice_ptr; } @@ -257,6 +261,11 @@ View::get_data( std::vector column_names; bool is_sorted = m_sorts.size() > 0; + if (is_column_only()) { + start_row += m_row_offset; + end_row += m_row_offset; + } + if (is_sorted) { /** * Perspective generates headers for sorted columns, so we have to @@ -297,8 +306,9 @@ View::get_data( column_names.insert(column_names.begin(), "__ROW_PATH__"); auto slice_ptr = std::make_shared>(slice); - auto data_slice_ptr = std::make_shared>( - m_ctx, start_row, end_row, start_col, end_col, slice_ptr, column_names, column_indices); + auto data_slice_ptr + = std::make_shared>(m_ctx, start_row, end_row, start_col, end_col, + m_row_offset, m_col_offset, slice_ptr, column_names, column_indices); return data_slice_ptr; } diff --git a/cpp/perspective/src/include/perspective/data_slice.h b/cpp/perspective/src/include/perspective/data_slice.h index d287c24fbe..a5c5692d6f 100644 --- a/cpp/perspective/src/include/perspective/data_slice.h +++ b/cpp/perspective/src/include/perspective/data_slice.h @@ -40,12 +40,12 @@ template class PERSPECTIVE_EXPORT t_data_slice { public: t_data_slice(std::shared_ptr ctx, t_uindex start_row, t_uindex end_row, - t_uindex start_col, t_uindex end_col, + t_uindex start_col, t_uindex end_col, t_uindex row_offset, t_uindex col_offset, const std::shared_ptr>& slice, std::vector column_names); t_data_slice(std::shared_ptr ctx, t_uindex start_row, t_uindex end_row, - t_uindex start_col, t_uindex end_col, + t_uindex start_col, t_uindex end_col, t_uindex row_offset, t_uindex col_offset, const std::shared_ptr>& slice, std::vector column_names, std::vector column_indices); @@ -97,6 +97,8 @@ class PERSPECTIVE_EXPORT t_data_slice { t_uindex m_end_row; t_uindex m_start_col; t_uindex m_end_col; + t_uindex m_row_offset; + t_uindex m_col_offset; t_uindex m_stride; std::shared_ptr> m_slice; std::vector m_column_names; diff --git a/cpp/perspective/src/include/perspective/view.h b/cpp/perspective/src/include/perspective/view.h index efe83397e4..3e48f9b962 100644 --- a/cpp/perspective/src/include/perspective/view.h +++ b/cpp/perspective/src/include/perspective/view.h @@ -162,6 +162,8 @@ class PERSPECTIVE_EXPORT View { std::vector m_filters; std::vector m_sorts; bool m_column_only; + t_uindex m_row_offset; + t_uindex m_col_offset; t_config m_config; }; diff --git a/packages/perspective/src/js/perspective.js b/packages/perspective/src/js/perspective.js index 19ce5a76d7..1931e9f94a 100644 --- a/packages/perspective/src/js/perspective.js +++ b/packages/perspective/src/js/perspective.js @@ -327,7 +327,7 @@ export default function(Module) { const viewport = this.config.viewport ? this.config.viewport : {}; const start_row = options.start_row || (viewport.top ? viewport.top : 0); - const end_row = (options.end_row || (viewport.height ? start_row + viewport.height : max_rows)) + (this.column_only ? 1 : 0); + const end_row = options.end_row || (viewport.height ? start_row + viewport.height : max_rows); const start_col = options.start_col || (viewport.left ? viewport.left : 0); const end_col = Math.min(max_cols, (options.end_col || (viewport.width ? start_col + viewport.width : max_cols)) * (hidden + 1)); @@ -363,9 +363,9 @@ export default function(Module) { formatter.addRow(data, row); } - if (this.column_only) { + /* if (this.column_only) { data = formatter.slice(data, 1); - } + } */ return formatter.formatData(data, options.config); }; @@ -950,7 +950,7 @@ export default function(Module) { throw new Error(`Duplicate configuration parameter "${key}"`); } } else if (key === "aggregate") { - console.warn(`Deprecated: "aggregate" config parameter has been replaced by "aggregates" amd "columns"`); + console.warn(`Deprecated: "aggregate" config parameter has been replaced by "aggregates" and "columns"`); config[key] = _config[key]; } else if (defaults.CONFIG_VALID_KEYS.indexOf(key) > -1) { config[key] = _config[key]; diff --git a/packages/perspective/test/js/to_format.js b/packages/perspective/test/js/to_format.js index 0d47439c0b..79e4eca910 100644 --- a/packages/perspective/test/js/to_format.js +++ b/packages/perspective/test/js/to_format.js @@ -16,7 +16,25 @@ var int_float_string_data = [ module.exports = perspective => { describe("data slice", function() { - it("data slice should respect start/end rows", async function() { + it("should filter out invalid start rows", async function() { + let table = perspective.table(int_float_string_data); + let view = table.view(); + let json = await view.to_json({ + start_row: 5 + }); + expect(json).toEqual([]); + }); + + it("should filter out invalid start columns", async function() { + let table = perspective.table(int_float_string_data); + let view = table.view(); + let json = await view.to_json({ + start_col: 5 + }); + expect(json).toEqual([{}, {}, {}, {}]); + }); + + it("should respect start/end rows", async function() { let table = perspective.table(int_float_string_data); let view = table.view(); let json = await view.to_json({ @@ -28,7 +46,7 @@ module.exports = perspective => { expect(json[0]).toEqual(comparator); }); - it("data slice should respect start/end columns", async function() { + it("should respect start/end columns", async function() { let table = perspective.table(int_float_string_data); let view = table.view(); let json = await view.to_columns({ @@ -72,6 +90,26 @@ module.exports = perspective => { } }); + it("column-only views should not have header rows", async function() { + let table = perspective.table([{x: 1, y: "a"}, {x: 2, y: "b"}]); + let view = table.view({ + column_pivots: ["x"] + }); + let json = await view.to_json(); + expect(json).toEqual([{"1|x": 1, "1|y": "a", "2|x": null, "2|y": null}, {"1|x": null, "1|y": null, "2|x": 2, "2|y": "b"}]); + }); + + it("column-only views should return correct windows of data", async function() { + let table = perspective.table([{x: 1, y: "a"}, {x: 2, y: "b"}]); + let view = table.view({ + column_pivots: ["x"] + }); + let json = await view.to_json({ + start_row: 1 + }); + expect(json).toEqual([{"1|x": null, "1|y": null, "2|x": 2, "2|y": "b"}]); + }); + it("two-sided views should have row paths", async function() { let table = perspective.table(int_float_string_data); let view = table.view({