From b16b360c11abb5e296f9620e4d838a34b88c2e72 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Sun, 23 Feb 2020 22:39:54 -0500 Subject: [PATCH 1/2] Fixed off-by-one issue in `end_col` in perspective.js, fixed lint error, fixed missing yarn.lock. --- .../perspective-workspace/src/js/index.js | 3 +- packages/perspective/src/js/perspective.js | 3 +- .../test/js/to_format_viewport.spec.js | 159 ++++++++++++++++++ yarn.lock | 15 -- 4 files changed, 163 insertions(+), 17 deletions(-) create mode 100644 packages/perspective/test/js/to_format_viewport.spec.js diff --git a/packages/perspective-workspace/src/js/index.js b/packages/perspective-workspace/src/js/index.js index 57543ce88f..2d50f28369 100644 --- a/packages/perspective-workspace/src/js/index.js +++ b/packages/perspective-workspace/src/js/index.js @@ -106,7 +106,8 @@ class PerspectiveWorkspaceElement extends HTMLElement { * `Table`s themselves must be added to the `tables` property `Map()` * separately. * - * @return {Object} A configuration token, compatible with `restore(config)`. + * @return {Object} A configuration token, compatible with + * `restore(config)`. * @example * // Save this layout to local storage * const workspace = document.querySelector("perspective-workspace"); diff --git a/packages/perspective/src/js/perspective.js b/packages/perspective/src/js/perspective.js index c804f345a2..d1e3e36d43 100644 --- a/packages/perspective/src/js/perspective.js +++ b/packages/perspective/src/js/perspective.js @@ -367,12 +367,13 @@ export default function(Module) { const max_cols = this._View.num_columns() + (this.sides() === 0 ? 0 : 1); const max_rows = this._View.num_rows(); const hidden = this._num_hidden(); + const psp_offset = this.sides() > 0 || this.column_only ? 1 : 0; const viewport = this.config.viewport ? this.config.viewport : {}; const start_row = options.start_row || (viewport.top ? viewport.top : 0); const end_row = Math.min(max_rows, options.end_row !== undefined ? 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 !== undefined ? options.end_col : viewport.width ? start_col + viewport.width : max_cols) * (hidden + 1)); + const end_col = Math.min(max_cols, (options.end_col !== undefined ? options.end_col + psp_offset : viewport.width ? start_col + viewport.width : max_cols) * (hidden + 1)); // Return the calculated values options.start_row = start_row; diff --git a/packages/perspective/test/js/to_format_viewport.spec.js b/packages/perspective/test/js/to_format_viewport.spec.js new file mode 100644 index 0000000000..0198401fd8 --- /dev/null +++ b/packages/perspective/test/js/to_format_viewport.spec.js @@ -0,0 +1,159 @@ +/****************************************************************************** + * + * Copyright (c) 2017, the Perspective Authors. + * + * This file is part of the Perspective library, distributed under the terms of + * the Apache License 2.0. The full license can be found in the LICENSE file. + * + */ + +const perspective = require("../../dist/cjs/perspective.node.js"); + +const data = { + w: [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, -1.5, -3.5, -1.5, -4.5, -9.5, -5.5, -8.5, -7.5], + x: [1, 2, 3, 4, 4, 3, 2, 1, 3, 4, 2, 1, 4, 3, 1, 2], + y: ["a", "b", "c", "d", "a", "b", "c", "d", "a", "b", "c", "d", "a", "b", "c", "d"], + z: [true, false, true, false, true, false, true, false, true, true, true, true, false, false, false, false] +}; + +describe("to_format viewport", function() { + describe("0 sided", function() { + it("start_col 0 is the first col", async function() { + var table = perspective.table(data); + var view = table.view({}); + const cols = await view.to_columns({start_col: 0, end_col: 1}); + expect(cols).toEqual({w: data.w}); + view.delete(); + table.delete(); + }); + + it("start_col 2 is the second col", async function() { + var table = perspective.table(data); + var view = table.view({}); + const cols = await view.to_columns({start_col: 1, end_col: 2}); + expect(cols).toEqual({x: data.x}); + view.delete(); + table.delete(); + }); + + it("start_col 0, end_col 2 is the first two columns", async function() { + var table = perspective.table(data); + var view = table.view({}); + const cols = await view.to_columns({start_col: 0, end_col: 2}); + expect(cols).toEqual({w: data.w, x: data.x}); + view.delete(); + table.delete(); + }); + }); + + describe("1 sided", function() { + it("start_col 0 is the first col", async function() { + var table = perspective.table(data); + var view = table.view({ + row_pivots: ["y"] + }); + const cols = await view.to_columns({start_col: 0, end_col: 1}); + expect(cols).toEqual({__ROW_PATH__: [[], ["a"], ["b"], ["c"], ["d"]], w: [-2, -4, 0, 1, 1]}); + view.delete(); + table.delete(); + }); + + it("start_col 2 is the second col", async function() { + var table = perspective.table(data); + var view = table.view({ + row_pivots: ["y"] + }); + const cols = await view.to_columns({start_col: 1, end_col: 2}); + expect(cols).toEqual({__ROW_PATH__: [[], ["a"], ["b"], ["c"], ["d"]], x: [40, 12, 12, 8, 8]}); + view.delete(); + table.delete(); + }); + + it("start_col 0, end_col 2 is the first two columns", async function() { + var table = perspective.table(data); + var view = table.view({ + row_pivots: ["y"] + }); + const cols = await view.to_columns({start_col: 0, end_col: 2}); + expect(cols).toEqual({__ROW_PATH__: [[], ["a"], ["b"], ["c"], ["d"]], w: [-2, -4, 0, 1, 1], x: [40, 12, 12, 8, 8]}); + view.delete(); + table.delete(); + }); + }); + + describe("2 sided", function() { + it("start_col 0 is the first col", async function() { + var table = perspective.table(data); + var view = table.view({ + row_pivots: ["y"], + column_pivots: ["z"] + }); + const cols = await view.to_columns({start_col: 0, end_col: 1}); + expect(cols).toEqual({__ROW_PATH__: [[], ["a"], ["b"], ["c"], ["d"]], "false|w": [-9, -9.5, 3.5, -8.5, 5.5]}); + view.delete(); + table.delete(); + }); + + it("start_col 2 is the second col", async function() { + var table = perspective.table(data); + var view = table.view({ + row_pivots: ["y"], + column_pivots: ["z"] + }); + const cols = await view.to_columns({start_col: 1, end_col: 2}); + expect(cols).toEqual({__ROW_PATH__: [[], ["a"], ["b"], ["c"], ["d"]], "false|x": [20, 4, 8, 1, 7]}); + view.delete(); + table.delete(); + }); + + it("start_col 0, end_col 2 is the first two columns", async function() { + var table = perspective.table(data); + var view = table.view({ + row_pivots: ["y"], + column_pivots: ["z"] + }); + const cols = await view.to_columns({start_col: 0, end_col: 2}); + expect(cols).toEqual({__ROW_PATH__: [[], ["a"], ["b"], ["c"], ["d"]], "false|w": [-9, -9.5, 3.5, -8.5, 5.5], "false|x": [20, 4, 8, 1, 7]}); + view.delete(); + table.delete(); + }); + }); + + describe("column only", function() { + it("start_col 0 is the first col", async function() { + var table = perspective.table(data); + var view = table.view({ + column_pivots: ["z"] + }); + const cols = await view.to_columns({start_col: 0, end_col: 1}); + expect(cols).toEqual({"false|w": [null, 2.5, null, 4.5, null, 6.5, null, 8.5, null, null, null, null, -9.5, -5.5, -8.5, -7.5]}); + view.delete(); + table.delete(); + }); + + it("start_col 2 is the second col", async function() { + var table = perspective.table(data); + var view = table.view({ + column_pivots: ["z"] + }); + const cols = await view.to_columns({start_col: 1, end_col: 2}); + expect(cols).toEqual({"false|x": [null, 2, null, 4, null, 3, null, 1, null, null, null, null, 4, 3, 1, 2]}); + view.delete(); + table.delete(); + }); + + it("start_col 0, end_col 2 is the first two columns", async function() { + var table = perspective.table(data); + var view = table.view({ + column_pivots: ["z"] + }); + const cols = await view.to_columns({start_col: 0, end_col: 2}); + expect(cols).toEqual({ + "false|w": [null, 2.5, null, 4.5, null, 6.5, null, 8.5, null, null, null, null, -9.5, -5.5, -8.5, -7.5], + "false|x": [null, 2, null, 4, null, 3, null, 1, null, null, null, null, 4, 3, 1, 2] + }); + view.delete(); + table.delete(); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 2f202e25e1..2d97360e55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5273,11 +5273,6 @@ diacritics-map@^0.1.0: resolved "https://registry.yarnpkg.com/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af" integrity sha1-bfwP+dAQAKLt8oZTccrDFulJd68= -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== - diff-sequences@^25.1.0: version "25.1.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" @@ -8465,16 +8460,6 @@ jest-config@^25.1.0: pretty-format "^25.1.0" realpath-native "^1.1.0" -jest-diff@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - jest-diff@^25.1.0: version "25.1.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.1.0.tgz#58b827e63edea1bc80c1de952b80cec9ac50e1ad" From 51175f0facd9766117c95e2cb3243b3d06d0ea59 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Mon, 24 Feb 2020 01:14:47 -0500 Subject: [PATCH 2/2] Fix windows webpack issue --- .../src/js/switch-inline-loader.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/perspective-webpack-plugin/src/js/switch-inline-loader.js b/packages/perspective-webpack-plugin/src/js/switch-inline-loader.js index f8ed1fb807..c436473b9b 100644 --- a/packages/perspective-webpack-plugin/src/js/switch-inline-loader.js +++ b/packages/perspective-webpack-plugin/src/js/switch-inline-loader.js @@ -7,12 +7,15 @@ * */ +const path = require("path"); + exports.default = function pitch(request) { return request; }; exports.pitch = function(request) { - return `module.exports = require("${request.replace("umd/perspective.inline", "esm/perspective.parallel")}");`; + const new_path = request.replace(/umd[/\\]perspective.inline/, path.join("esm", "perspective.parallel")).replace(/\\/g, "\\\\"); + return `module.exports = require("${new_path}");`; }; exports.raw = true;