diff --git a/packages/perspective-viewer-d3fc/src/ts/tooltip/selectionData.ts b/packages/perspective-viewer-d3fc/src/ts/tooltip/selectionData.ts index 345822a40e..2f55586579 100644 --- a/packages/perspective-viewer-d3fc/src/ts/tooltip/selectionData.ts +++ b/packages/perspective-viewer-d3fc/src/ts/tooltip/selectionData.ts @@ -70,7 +70,10 @@ export function getDataValues(data, settings) { } return settings.mainValues.map((main) => ({ name: main.name, - value: toValue(main.type, data.row[main.name]), + value: toValue( + main.type, + data.row[getDataRowKey(data.key, main, settings.realValues)] + ), })); } return [ @@ -86,3 +89,33 @@ export function getDataValues(data, settings) { }, ]; } + +function getDataRowKey(key, main, realValues) { + if (!key) { + return main.name; + } + + if (key.includes("|")) { + const splitKey = key.split("|"); + const keyIncludesValidValueName = + splitKey[splitKey.length - 1] === main.name; + + if (keyIncludesValidValueName) { + return key; + } + + const keyIncludesInvalidValueName = realValues.includes( + splitKey[splitKey.length - 1] + ); + + const validKeyPrefix = keyIncludesInvalidValueName + ? splitKey.slice(0, splitKey.length - 1).join("|") + : key; + + return `${validKeyPrefix}|${main.name}`; + } + + const keyIsRealValue = realValues.includes(key); + + return keyIsRealValue ? main.name : `${key}|${main.name}`; +} diff --git a/packages/perspective-viewer-d3fc/test/js/splitby.spec.ts b/packages/perspective-viewer-d3fc/test/js/splitby.spec.ts new file mode 100644 index 0000000000..12bfc4d4ef --- /dev/null +++ b/packages/perspective-viewer-d3fc/test/js/splitby.spec.ts @@ -0,0 +1,133 @@ +// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ +// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ +// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ +// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ +// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ +// ┃ Copyright (c) 2017, the Perspective Authors. ┃ +// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ +// ┃ This file is part of the Perspective library, distributed under the terms ┃ +// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ +// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + +import { expect, test } from "@finos/perspective-test"; + +test.describe("Tooltip data values with various 'Split By' configurations", () => { + test("Show valid tooltip data with no 'Split By' configuration", async ({ + page, + }) => { + await page.goto("/tools/perspective-test/src/html/basic-test.html"); + await page.evaluate(async () => { + while (!window["__TEST_PERSPECTIVE_READY__"]) { + await new Promise((x) => setTimeout(x, 10)); + } + }); + + await page.evaluate(async () => { + await document.querySelector("perspective-viewer")!.restore({ + plugin: "X/Y Line", + settings: true, + columns: ["Row ID", "Postal Code", null], + group_by: [], + split_by: [], + }); + }); + + await page.hover( + "#container > d3fc-group > d3fc-svg.svg-plot-area.plot-area > svg > g:nth-child(2) > g > g:nth-child(1) > g > path", + { + force: true, + } + ); + await page.waitForSelector("#tooltip-values > li:nth-child(1)"); + + let tooltip_row_id_value = await page.evaluate(async () => { + return document + .querySelector("perspective-viewer-d3fc-xyline") + ?.shadowRoot?.querySelector( + "#tooltip-values > li:nth-child(2) > b" + )?.textContent; + }); + + expect(tooltip_row_id_value).toBeTruthy(); + expect(tooltip_row_id_value).toMatch(/^(?!NaN$|-$).+$/); + }); + test("Show valid tooltip data with one 'Split By' configuration", async ({ + page, + }) => { + await page.goto("/tools/perspective-test/src/html/basic-test.html"); + await page.evaluate(async () => { + while (!window["__TEST_PERSPECTIVE_READY__"]) { + await new Promise((x) => setTimeout(x, 10)); + } + }); + + await page.evaluate(async () => { + await document.querySelector("perspective-viewer")!.restore({ + plugin: "X/Y Line", + settings: true, + columns: ["Row ID", "Postal Code", null], + group_by: [], + split_by: ["Sub-Category"], + }); + }); + + await page.hover( + "#container > d3fc-group > d3fc-svg.svg-plot-area.plot-area > svg > g:nth-child(2) > g > g:nth-child(1) > g > path", + { + force: true, + } + ); + await page.waitForSelector("#tooltip-values > li:nth-child(2)"); + + let tooltip_row_id_value = await page.evaluate(async () => { + return document + .querySelector("perspective-viewer-d3fc-xyline") + ?.shadowRoot?.querySelector( + "#tooltip-values > li:nth-child(2) > b" + )?.textContent; + }); + + expect(tooltip_row_id_value).toBeTruthy(); + expect(tooltip_row_id_value).toMatch(/^(?!NaN$|-$).+$/); + }); + test("Show valid tooltip data with multiple 'Split By' configuration", async ({ + page, + }) => { + await page.goto("/tools/perspective-test/src/html/basic-test.html"); + await page.evaluate(async () => { + while (!window["__TEST_PERSPECTIVE_READY__"]) { + await new Promise((x) => setTimeout(x, 10)); + } + }); + + await page.evaluate(async () => { + await document.querySelector("perspective-viewer")!.restore({ + plugin: "X/Y Line", + settings: true, + columns: ["Row ID", "Postal Code", null], + group_by: [], + split_by: ["Sub-Category", "Segment"], + }); + }); + + await page.hover( + "#container > d3fc-group > d3fc-svg.svg-plot-area.plot-area > svg > g:nth-child(2) > g > g:nth-child(1) > g > path", + { + force: true, + } + ); + await page.waitForSelector("#tooltip-values > li:nth-child(3)"); + + let tooltip_row_id_value = await page.evaluate(async () => { + return document + .querySelector("perspective-viewer-d3fc-xyline") + ?.shadowRoot?.querySelector( + "#tooltip-values > li:nth-child(2) > b" + )?.textContent; + }); + + expect(tooltip_row_id_value).toBeTruthy(); + expect(tooltip_row_id_value).toMatch(/^(?!NaN$|-$).+$/); + }); +});